⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vm_socket_win32.c

📁 audio-video-codecs.rar语音编解码器
💻 C
字号:
/*
//
//                  INTEL CORPORATION PROPRIETARY INFORMATION
//     This software is supplied under the terms of a license agreement or
//     nondisclosure agreement with Intel Corporation and may not be copied
//     or disclosed except in accordance with the terms of that agreement.
//       Copyright(c) 2003-2007 Intel Corporation. All Rights Reserved.
//
*/

#include "vm_socket.h"
#include "vm_time.h"
#include "vm_debug.h"

#if defined(_WIN32) || defined(_WIN64)

#if defined(_WIN32_WINNT) && (WINVER < 0x0501)
#include <ws2tcpip.h>
#endif /* defined(_WIN32_WINNT) && (WINVER < 0x0501) */

#define LINE_SIZE 128

static
Ipp32s fill_sockaddr(struct sockaddr_in *iaddr, vm_socket_host *host)
{
    struct hostent *ent;
    Ipp8s hostname[LINE_SIZE];

    memset(iaddr, 0, sizeof(*iaddr));

    iaddr->sin_family      = AF_INET;
    iaddr->sin_port        = host ? htons(host->port) : 0;
    iaddr->sin_addr.s_addr = htons(INADDR_ANY);

    if (!host)
        return 0;
    if (!host->hostname)
        return 0;

#if defined(UNICODE) || defined(_UNICODE)
    wcstombs(hostname, host->hostname, LINE_SIZE);
#else /* defined(UNICODE) || defined(_UNICODE) */
    strncpy(hostname, host->hostname, LINE_SIZE);
#endif /* defined(UNICODE) || defined(_UNICODE) */
    iaddr->sin_addr.s_addr = inet_addr(hostname);
    if (iaddr->sin_addr.s_addr != INADDR_NONE)
        return 0;

    ent = gethostbyname(hostname);
    if (!ent)
        return 1;
    iaddr->sin_addr.s_addr = *((u_long *)ent->h_addr_list[0]);

    return 0;

} /* Ipp32s fill_sockaddr(struct sockaddr_in *iaddr, vm_socket_host *host) */


vm_status vm_socket_init(vm_socket *hd,
                         vm_socket_host *local,
                         vm_socket_host *remote,
                         Ipp32s flags)
{
    Ipp32s i;
    Ipp32s error = 0;
    Ipp32s connection_attempts = 7, reattempt = 0;
      WSADATA wsaData;

    if (WSAStartup(MAKEWORD(1,1), &wsaData))
        return VM_OPERATION_FAILED;

    /* clean everything */
    for (i = 0; i <= VM_SOCKET_QUEUE; i++)hd->chns[i] = INVALID_SOCKET;

    FD_ZERO(&hd->r_set);
    FD_ZERO(&hd->w_set);

    /* flags shaping */
    if (flags & VM_SOCKET_MCAST)
    {    flags |= VM_SOCKET_UDP; }

    hd->flags=flags;

    /* create socket */
    hd->chns[0] = socket(AF_INET,
                         (flags&VM_SOCKET_UDP) ? SOCK_DGRAM : SOCK_STREAM,
                         0);

    if (hd->chns[0] == INVALID_SOCKET)
        return VM_OPERATION_FAILED;

    if (fill_sockaddr(&hd->sal, local))
        return VM_OPERATION_FAILED;

    if (fill_sockaddr(&hd->sar, remote))
        return VM_OPERATION_FAILED;

    if (bind(hd->chns[0], (struct sockaddr*)&hd->sal, sizeof(hd->sal)))
        return VM_OPERATION_FAILED;

    if (flags & VM_SOCKET_SERVER)
    {
        if (flags & VM_SOCKET_UDP)
            return VM_OK;
        if (listen(hd->chns[0], VM_SOCKET_QUEUE))
            return VM_OPERATION_FAILED;

        return VM_OK;
    }

    /* network client */
    if (flags & VM_SOCKET_MCAST)
    {
        struct ip_mreq imr;

        imr.imr_multiaddr.s_addr = hd->sar.sin_addr.s_addr;
        imr.imr_interface.s_addr = INADDR_ANY;
        if (setsockopt(hd->chns[0],
            IPPROTO_IP,
            IP_ADD_MEMBERSHIP,
            (Ipp8s *) &imr,
                    sizeof(imr))==SOCKET_ERROR)
              return VM_OPERATION_FAILED;
    }

    if (flags & VM_SOCKET_UDP)
        return VM_OK;

    while (connect(hd->chns[0], (struct sockaddr *)&hd->sar, sizeof(hd->sar)) &&
        reattempt < connection_attempts )

    {
        error = WSAGetLastError();

        if (error ==  WSAENETUNREACH || error == WSAECONNREFUSED
            || error ==  WSAEADDRINUSE || error ==  WSAETIMEDOUT)
        {
            reattempt++;
            vm_debug_trace(-1, reattempt);
        }
        else
        {
            vm_debug_trace(-1, reattempt);
            return VM_OPERATION_FAILED;
        }
        vm_time_sleep(1);
    }
    return VM_OK;
} /* vm_status vm_socket_init(vm_socket *hd, */

Ipp32s vm_socket_select(vm_socket *hds, Ipp32s nhd, Ipp32s masks)
{
    Ipp32s i, j;

    FD_ZERO(&hds->r_set);
    FD_ZERO(&hds->w_set);

    for (i = 0; i < nhd; i++)
    {
        Ipp32s flags = hds[i].flags;
        if (hds[i].chns[0] == INVALID_SOCKET)
            continue;

        if (masks & VM_SOCKET_ACCEPT ||
                (masks & VM_SOCKET_READ &&
                 (flags & VM_SOCKET_UDP || !(flags & VM_SOCKET_SERVER))))
            FD_SET(hds[i].chns[0], &hds->r_set);

        if (masks & VM_SOCKET_WRITE &&
                (flags & VM_SOCKET_UDP || !(flags & VM_SOCKET_SERVER)))
            FD_SET(hds[i].chns[0], &hds->w_set);

        for (j = 1; j <= VM_SOCKET_QUEUE; j++)
        {
            if (hds[i].chns[j] == INVALID_SOCKET)
                continue;

            if (masks & VM_SOCKET_READ)
                FD_SET(hds[i].chns[j], &hds->r_set);
            if (masks & VM_SOCKET_WRITE)
                FD_SET(hds[i].chns[j], &hds->w_set);
        }
    }

    i = select(0, &hds->r_set, &hds->w_set, 0, 0);

    return (i < 0) ? -1 : i;

} /* Ipp32s vm_socket_select(vm_socket *hds, Ipp32s nhd, Ipp32s masks) */

Ipp32s vm_socket_next(vm_socket *hds, Ipp32s nhd, Ipp32s *idx, Ipp32s *chn, Ipp32s *type)
{
    Ipp32s i, j;

    for (i = 0; i < nhd; i++)
    {
        for (j = 0; j <= VM_SOCKET_QUEUE; j++)
        {
            Ipp32s flags = hds[i].flags;
            if (hds[i].chns[j] == INVALID_SOCKET)
                continue;

            if (FD_ISSET(hds[i].chns[j], &hds->r_set))
            {
                FD_CLR(hds[i].chns[j],&hds->r_set);

                if (idx)
                    *idx=i;
                if (chn)
                    *chn=j;
                if (type)
                {
                    *type = VM_SOCKET_READ;
                    if (j > 0)
                        return 1;
                    if (flags&VM_SOCKET_UDP)
                        return 1;
                    if (flags&VM_SOCKET_SERVER)
                        *type=VM_SOCKET_ACCEPT;
                }
                return 1;
            }

            if (FD_ISSET(hds[i].chns[j],&hds->w_set))
            {
                FD_CLR(hds[i].chns[j],&hds->w_set);

                if (idx)
                    *idx=i;
                if (chn)
                    *chn=j;
                if (type)
                    *type=VM_SOCKET_WRITE;
                return 1;
            }
        }
    }

    return 0;

} /* Ipp32s vm_socket_next(vm_socket *hds, Ipp32s nhd, Ipp32s *idx, Ipp32s *chn, Ipp32s *type) */

Ipp32s vm_socket_accept(vm_socket *hd)
{
    Ipp32s psize, chn;

    if (hd->chns[0] == INVALID_SOCKET)
        return -1;
    if (hd->flags & VM_SOCKET_UDP)
        return 0;
    if (!(hd->flags & VM_SOCKET_SERVER))
        return 0;

    for (chn = 1; chn <= VM_SOCKET_QUEUE; chn++)
    {
        if (hd->chns[chn] == INVALID_SOCKET)
            break;
    }
    if (chn > VM_SOCKET_QUEUE)
        return -1;

    psize = sizeof(hd->peers[chn]);
    hd->chns[chn] = accept(hd->chns[0], (struct sockaddr *)&(hd->peers[chn]), &psize);
    if (hd->chns[chn] == INVALID_SOCKET)
    {
        memset(&(hd->peers[chn]), 0, sizeof(hd->peers[chn]));
        return -1;
    }

    return chn;

} /* Ipp32s vm_socket_accept(vm_socket *hd) */

Ipp32s vm_socket_read(vm_socket *hd, Ipp32s chn, void *buffer, Ipp32s nbytes)
{
    Ipp32s retr;

    if (chn < 0 || chn > VM_SOCKET_QUEUE)
        return -1;
    if (hd->chns[chn] == INVALID_SOCKET)
        return -1;

    if (hd->flags & VM_SOCKET_UDP)
    {
        Ipp32s ssize = sizeof(hd->sar);
        retr = recvfrom(hd->chns[chn],
                        buffer,
                        nbytes,
                        0,
                        (struct sockaddr *)&hd->sar,
                        &ssize);
    }
    else
    {
        Ipp32s time_out_count = 0;

        retr = recv(hd->chns[chn], buffer, nbytes, 0);

        // Process 2 seconds time out
        while (retr < 0 && WSAEWOULDBLOCK == WSAGetLastError() && ++time_out_count < 20000)
        {
            vm_time_sleep(1);
            retr = recv(hd->chns[chn], buffer, nbytes, 0);
        }
    }

    if (retr < 1)
        vm_socket_close_chn(hd, chn);

    return retr;

} /* Ipp32s vm_socket_read(vm_socket *hd, Ipp32s chn, void *buffer, Ipp32s nbytes) */

Ipp32s vm_socket_write(vm_socket *hd, Ipp32s chn, void *buffer, Ipp32s nbytes)
{
    Ipp32s retw;

    if (chn < 0 || chn > VM_SOCKET_QUEUE)
        return -1;
    if (hd->chns[chn] == INVALID_SOCKET)
        return -1;

    if (hd->flags & VM_SOCKET_UDP)
    {
        retw = sendto(hd->chns[chn],
                      buffer,
                      nbytes,
                      0,
                      (struct sockaddr *)&hd->sar,
                      sizeof(hd->sar));
    }
    else
    {
        retw = send(hd->chns[chn], buffer, nbytes, 0);
    }

    if (retw < 1)
        vm_socket_close_chn(hd, chn);

    return retw;

} /* Ipp32s vm_socket_write(vm_socket *hd, Ipp32s chn, void *buffer, Ipp32s nbytes) */

void vm_socket_close_chn(vm_socket *hd, Ipp32s chn)
{
    if (hd->chns[chn] != INVALID_SOCKET)
        closesocket(hd->chns[chn]);

    hd->chns[chn] = INVALID_SOCKET;

} /* void vm_socket_close_chn(vm_socket *hd, Ipp32s chn) */

void vm_socket_close(vm_socket *hd)
{
    Ipp32s i;

    if ((hd->flags & VM_SOCKET_MCAST) && !(hd->flags&VM_SOCKET_SERVER))
    {
        struct ip_mreq imr;

        imr.imr_multiaddr.s_addr = hd->sar.sin_addr.s_addr;
        imr.imr_interface.s_addr = INADDR_ANY;
        setsockopt(hd->chns[0],
                IPPROTO_IP,
                IP_DROP_MEMBERSHIP,
                (Ipp8s *) &imr,
                sizeof(imr));
    }
    for (i= VM_SOCKET_QUEUE; i >= 0; i--)
        vm_socket_close_chn(hd, i);

    WSACleanup();
} /* void vm_socket_close(vm_socket *hd) */

#endif /* defined(_WIN32) || defined(_WIN64) */

/* Old part */
#if defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE)

Ipp32s vm_sock_startup(vm_char a, vm_char b)
{
    Ipp16u wVersionRequested = MAKEWORD(a, b);
    WSADATA wsaData;
    Ipp32s nRet;

    /*
    // Initialize WinSock and check version
    */
    nRet = WSAStartup(wVersionRequested, &wsaData);
    if (wsaData.wVersion != wVersionRequested)
    {
        return 1;
    }

    return 0;

} /* Ipp32s vm_sock_startup(vm_char a, vm_char b) */

Ipp32s vm_sock_cleanup(void)
{
    return WSACleanup();

} /* Ipp32s vm_sock_cleanup(void) */

Ipp32u vm_inet_addr(const vm_char *szName)
{
    Ipp32u ulRes;

#if defined(UNICODE)||defined(_UNICODE)

    Ipp32s iStrSize = vm_string_strlen(szName);
    Ipp8s *szAnciStr = malloc(iStrSize + 2);

    if (NULL == szAnciStr)
        return INADDR_NONE;
    if (0 == WideCharToMultiByte(CP_ACP, 0, szName, iStrSize, szAnciStr,
                                 iStrSize + 2, 0, NULL))
    {
        free(szAnciStr);
        return INADDR_NONE;
    }
    ulRes = inet_addr(szAnciStr);
    free(szAnciStr);

#else /* defined(UNICODE)||defined(_UNICODE) */

    ulRes = inet_addr(szName);

#endif /* defined(UNICODE)||defined(_UNICODE) */

    return ulRes;

} /* Ipp32u vm_inet_addr(const vm_char *szName) */

struct hostent *vm_gethostbyname(const vm_char *szName)
{
    struct hostent *pRes = NULL;

#if defined(UNICODE)||defined(_UNICODE)

    Ipp32s iStrSize = vm_string_strlen(szName);
    Ipp8s *szAnciStr = malloc(iStrSize + 2);

    if (NULL == szAnciStr)
        return NULL;
    if (0 == WideCharToMultiByte(CP_ACP, 0, szName, iStrSize, szAnciStr,
                                 iStrSize + 2, 0, NULL))
    {
        free(szAnciStr);
        return NULL;
    }

    pRes = gethostbyname(szAnciStr);
    free(szAnciStr);

#else /* defined(UNICODE)||defined(_UNICODE) */

    pRes = gethostbyname(szName);

#endif /* defined(UNICODE)||defined(_UNICODE) */

    return pRes;

} /* struct hostent *vm_gethostbyname(const vm_char *szName) */

Ipp32s vm_sock_host_by_name(vm_char * name, struct in_addr * paddr)
{
    LPHOSTENT lpHostEntry;

    paddr->S_un.S_addr = vm_inet_addr(name);

    if (paddr->S_un.S_addr == INADDR_NONE)
    {
        lpHostEntry = vm_gethostbyname(name);
        if (NULL == lpHostEntry)
            return 1;
        else
            *paddr = *((LPIN_ADDR)*lpHostEntry->h_addr_list);
    }

    return 0;

} /* Ipp32s vm_sock_host_by_name(vm_char * name,struct in_addr * paddr) */

Ipp32s vm_socket_get_client_ip(vm_socket *hd, Ipp8u* buffer, Ipp32s len)
{
    Ipp32s iplen;
    if (hd == NULL)
        return -1;
    if (hd->chns[0] == INVALID_SOCKET)
        return -1;

    iplen = strlen(inet_ntoa(hd->sal.sin_addr));

    if (iplen >= len || buffer == NULL)
        return -1;

    memcpy(buffer,inet_ntoa(hd->sal.sin_addr),iplen);
    buffer[iplen]='\0';

    return 0;
}
#endif /* defined(_WIN32) || defined(_WIN64) || defined(_WIN32_WCE) */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -