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

📄 rvsocket.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
RvStatus RVCALLCONV RvSocketSendBuffer(
    IN  RvSocket*   sock,
    IN  RvUint8*    buffer,
    IN  RvSize_t    bytesToSend,
    IN  RvAddress*  remoteAddress,
    OUT RvSize_t*   bytesSent)
{
    RvSocket ourSocket;
    RvStatus ret;
    int errLen = 0;
    int socketError = 0;

    ret = RvSocketSharerShare(sock, &ourSocket);
    if (ret != RV_OK)
        return ret;

    if (remoteAddress == NULL)
    {
#if (RV_OS_TYPE == RV_OS_TYPE_OSE)
        errLen = inet_send(ourSocket, (char *)buffer, (int)bytesToSend, 0);
#elif (RV_OS_TYPE == RV_OS_TYPE_NUCLEUS)
        errLen = NU_Send(ourSocket, (char *)buffer, (int)bytesToSend, 0);
#else
        errLen = send(ourSocket, (char *)buffer, (int)bytesToSend, 0);
#endif
    }
    else
    {
        RvUint8 sockdata[RV_SOCKET_SOCKADDR_SIZE];
        int socklen;

        ret = RvSocketAddressToSockAddr(remoteAddress, (RV_SOCKADDR_PTR)sockdata, &socklen);

#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)
        if (ret == RV_OK)
            errLen = sendto(ourSocket, (char *)buffer, (int)bytesToSend, 0, (RV_SOCKADDR_PTR)sockdata, socklen);
#else
        if (ret == RV_OK)
            errLen = NU_Send_To(ourSocket, (char *)buffer, (int)bytesToSend, 0, (RV_SOCKADDR_PTR)sockdata, socklen);
#endif
    }

#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)  /* (nucleus does not have WOULDBLOCK event) */
    if (ret == RV_OK)
    {
        if (errLen > 0)
        {
            if (bytesSent != NULL)
                *bytesSent = errLen;
        }
        else
        {
            /* We had an error - check to see if it's WOULDBLOCK */
            socketError = RvSocketErrNo;
            if (!RvSocketErrorWouldBlock(socketError))
            {
                /* An error which is not "Would block" - return an error status */
                ret = RvSocketErrorCode(RV_ERROR_UNKNOWN);
                if (bytesSent != NULL)
                    *bytesSent = 0;
            }
        }
    }
#endif

#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_DEBUG)
    if (ret == RV_OK)
    {
        RvChar addr[RV_ADDRESS_MAXSTRINGSIZE];
        if (remoteAddress != NULL)
            RvAddressGetString(remoteAddress, addr, sizeof(addr));
        else
            addr[0] = '\0';
        RvLogDebug(&rvSocketLogSource, (&rvSocketLogSource,
            "RvSocketSendBuffer(sock=%d,addr=%s:%d,buf=0x%p,len=%d,sent=%d)=0",
            *sock, addr, RvAddressGetIpPort(remoteAddress), buffer, bytesToSend, errLen));
    }
#endif

#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_ERROR)
    if (ret != RV_OK)
    {
        RvChar addr[RV_ADDRESS_MAXSTRINGSIZE];
        if (remoteAddress != NULL)
            RvAddressGetString(remoteAddress, addr, sizeof(addr));
        else
            addr[0] = '\0';
        RvLogError(&rvSocketLogSource, (&rvSocketLogSource,
            "RvSocketSendBuffer(sock=%d,addr=%s:%d,buf=0x%p,len=%d,errno=%d)=%d",
            *sock, addr, RvAddressGetIpPort(remoteAddress), buffer, bytesToSend, socketError, ret));
    }
#endif

    RvSocketSharerClose(&ourSocket);

    return ret;
}


/********************************************************************************************
 * RvSocketReceiveBuffer
 *
 * purpose : Receive a buffer from a connection
 * input   : sock         - Socket to receive the buffer from
 *           buffer         - Buffer to use for received data
 *           bytesToReceive - Number of bytes available on the given buffer
 * output  : bytesReceived  - Number of bytes that were actually received
 *           remoteAddress  - Address buffer was received from
 *                            Can be given as NULL on connection-oriented sockets (TCP).
 *                            This address is constructed by this function and should be
 *                            destructed by the caller to this function
 * return  : RV_OK on success, other on failure
 * notes   : A blocked socket returns RV_OK with bytesReceived=0
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSocketReceiveBuffer(
    IN  RvSocket*   sock,
    IN  RvUint8*    buffer,
    IN  RvSize_t    bytesToReceive,
    OUT RvSize_t*   bytesReceived,
    OUT RvAddress*  remoteAddress)
{
    RvSocket ourSocket;
    RvStatus ret;
    int errLen;
    int socketError = 0;

    ret = RvSocketSharerShare(sock, &ourSocket);
    if (ret != RV_OK)
        return ret;

    if (remoteAddress == NULL)
    {
#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)
        errLen = recv(ourSocket, (char *)buffer, (int)bytesToReceive, 0);
#else
        errLen = NU_Recv(ourSocket, (char *)buffer, (int)bytesToReceive, 0);
#endif
    }
    else
    {
        RvUint8 sockdata[RV_SOCKET_SOCKADDR_SIZE];
        int socklen = RV_SOCKET_SOCKADDR_SIZE;
#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)
        errLen = recvfrom(ourSocket, (char *)buffer, (int)bytesToReceive, 0, (RV_SOCKADDR_PTR)sockdata, &socklen);
#else
        errLen = NU_Recv_From(ourSocket, (char *)buffer, (int)bytesToReceive, 0, (RV_SOCKADDR_PTR)sockdata, (RvInt16*)&socklen);
#endif
        if (errLen > 0)
            RvSocketSockAddrToAddress(sockdata, socklen, remoteAddress);
    }

    if (errLen >= 0)
    {
        if (bytesReceived)
            *bytesReceived = (RvSize_t)errLen;
    }
    else
    {
#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)
        /* We had an error - check to see if it's WOULDBLOCK */
        socketError = RvSocketErrNo;
        if (!RvSocketErrorWouldBlock(socketError))
        {
            /* An error which is not "Would block" - return an error status */
            ret = RvSocketErrorCode(RV_ERROR_UNKNOWN);
        }
#endif
        if (bytesReceived)
            *bytesReceived = 0;
    }

    RvSocketSharerClose(&ourSocket);

#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_DEBUG)
    if (ret == RV_OK)
    {
        RvChar addr[RV_ADDRESS_MAXSTRINGSIZE];
        if (remoteAddress != NULL)
            RvAddressGetString(remoteAddress, addr, sizeof(addr));
        else
            addr[0] = '\0';
        RvLogDebug(&rvSocketLogSource, (&rvSocketLogSource,
            "RvSocketReceiveBuffer(sock=%d,addr=%s:%d,buf=0x%p,len=%d,received=%d)=0",
            *sock, addr, RvAddressGetIpPort(remoteAddress), buffer, bytesToReceive, errLen));
    }
#endif

#if (RV_LOGMASK_COMPILEMASK & RV_LOGLEVEL_ERROR)
    if (ret != RV_OK)
    {
        RvLogError(&rvSocketLogSource, (&rvSocketLogSource,
            "RvSocketReceiveBuffer(sock=%d,buf=0x%p,len=%d,errno=%d)=%d",
            *sock, buffer, bytesToReceive, socketError, ret));
    }
#endif

    return ret;
}


RVCOREAPI
RvStatus RVCALLCONV RvSocketSetBuffers(IN RvSocket *sock, IN RvInt32 sendSize, IN RvInt32 recvSize)
{
    RvSocket ourSocket;
    RvStatus ret = RvSocketErrorCode(RV_ERROR_NOTSUPPORTED);
    int buflen=0;

#if (RV_OS_TYPE != RV_OS_TYPE_NUCLEUS)  /* can't set buffer sizes in nucleus */
    ret = RvSocketSharerShare(sock, &ourSocket);
    if (ret != RV_OK)
        return ret;

    if (recvSize >= 0)
    {
        buflen = (int)recvSize;
        if (RvSocketSetSockOpt(&ourSocket, SOL_SOCKET, SO_RCVBUF, (char*)&buflen, sizeof(buflen)) != 0)
            ret = RvSocketErrorCode(RV_ERROR_UNKNOWN);
    }

    if (sendSize >= 0)
    {
        buflen = (int)sendSize;
        if (RvSocketSetSockOpt(&ourSocket, SOL_SOCKET, SO_SNDBUF, (char*)&buflen, sizeof(buflen)) != 0)
            ret = RvSocketErrorCode(RV_ERROR_UNKNOWN);
    }

    RvSocketSharerClose(&ourSocket);
#endif

    return ret;
}


/********************************************************************************************
 * RvSocketSetLinger
 *
 * purpose : Set the linger time after socket is closed.
 * input   : sock       - Socket to modify
 *           lingerTime - Time to linger in seconds
 *                        Setting this parameter to -1 sets linger off for this socket
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSocketSetLinger(IN RvSocket *sock, IN RvInt32 lingerTime)
{
#if (RV_OS_TYPE == RV_OS_TYPE_OSE) || (RV_OS_TYPE == RV_OS_TYPE_NUCLEUS)
    /* Linger parameter of a socket is not supported in OSE & NUCLEUS */
    return RvSocketErrorCode(RV_ERROR_NOTSUPPORTED);

#else
    RvStatus status = RV_OK;
    struct linger lingerParam;


    if (lingerTime >= 0)
    {
        lingerParam.l_onoff = RV_TRUE;
        lingerParam.l_linger = (RV_LINGER_VALUE_TYPE)lingerTime;
    }
    else
    {
        lingerParam.l_onoff = RV_FALSE;
        lingerParam.l_linger = 0;
    }

    if (RvSocketSetSockOpt(sock, SOL_SOCKET, SO_LINGER, (char *)&lingerParam, sizeof(lingerParam)) != 0)
    {
        status = RvSocketErrorCode(RV_ERROR_UNKNOWN);
        RvLogError(&rvSocketLogSource, (&rvSocketLogSource,
            "RvSocketSetLinger(sock=%d,linger=%d,errno=%d)=%d",
            *sock, lingerTime, RvSocketErrNo, status));
    }

    return status;
#endif
}


/********************************************************************************************
 * RvSocketReuseAddr
 *
 * purpose : Set the socket as a reusable one (in terms of its address)
 *           This allows a TCP server socket and UDP multicast addresses to be used by
 *           other processes on the same machine as well.
 *           This function has to be called before RvSocketBind().
 * input   : sock     - Socket to modify
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSocketReuseAddr(IN RvSocket *sock)
{
#if (RV_OS_TYPE == RV_OS_TYPE_NUCLEUS)
    /* Reuse address parameter of a socket is not supported in NUCLEUS */
    return RvSocketErrorCode(RV_ERROR_NOTSUPPORTED);

#else
    RvStatus ret = RV_OK;
    int yes = RV_TRUE;

    if (RvSocketSetSockOpt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) != 0)
        ret = RvSocketErrorCode(RV_ERROR_UNKNOWN);

    return ret;
#endif
}


/********************************************************************************************
 * RvSocketSetBlocking
 *
 * purpose : Set blocking/non-blocking mode on a socket
 * input   : sock       - Socket to modify
 *           isBlocking - RV_TRUE for a blocking socket
 *                        RV_FALSE for a non-blocking socket
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSocketSetBlocking(IN RvSocket *sock, IN RvBool isBlocking)
{
    RvSocket ourSocket;
    RvStatus status;
    int res;

    status = RvSocketSharerShare(sock, &ourSocket);
    if (status != RV_OK)
        return status;

#if (RV_SOCKET_TYPE == RV_SOCKET_WIN32_WSA)
    {
        RV_IOCTL_ARGP_TYPE on = !isBlocking;
        res = ioctlsocket(ourSocket, FIONBIO, &on);
    }

#elif (RV_SOCKET_TYPE == RV_SOCKET_NUCLEUS)
    if (isBlocking)
        res = NU_Fcntl(ourSocket, NU_SETFLAG, NU_BLOCK);
    else
        res = NU_Fcntl(ourSocket, NU_SETFLAG, NU_FALSE);

#else
    {
        RV_IOCTL_ARGP_TYPE on = !isBlocking;
        res = ioctl(ourSocket, FIONBIO, (RV_IOCTL_ARGP_TYPE*) &on);
    }
#endif

    if (res < 0)
        status = RvSocketErrorCode(RV_ERROR_UNKNOWN);

    RvSocketSharerClose(&ourSocket);

    return status;
}


/********************************************************************************************
 * RvSocketSetBroadcast
 *
 * purpose : Set permission for sending broadcast datagrams on a socket
 * input   : sock           - Socket to modify
 *           canBroadcast   - RV_TRUE for permitting broadcast
 *                            RV_FALSE for not permitting broadcast
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSocketSetBroadcast(IN RvSocket *sock, IN RvBool canBroadcast)
{
    RvStatus ret = RV_OK;
    int on = (int)canBroadcast;

    if (RvSocketSetSockOpt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&on, sizeof(on)) != 0)
        ret = RvSocketErrorCode(RV_ERROR_UNKNOWN);

    return ret;
}


/********************************************************************************************
 * RvSocketSetMulticastTtl
 *
 * purpose : Set the TTL to use for multicast sockets (UDP)
 * input   : sock       - Socket to modify
 *           ttl        - TTL to set
 * output  : None
 * return  : RV_OK on success, other on failure
 ********************************************************************************************/
RVCOREAPI
RvStatus RVCALLCONV RvSocketSetMulticastTtl(IN RvSocket *sock, IN RvInt32 ttl)
{
    RvStatus ret = RV_OK;

#if RV_SOCKET_HAS_IPV6

⌨️ 快捷键说明

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