xuejianhui

导航

初解禁:供SDK服务端调用函数--02

/****************************************************************************************************
函 数 名:   BuildTcpSocket
功能描述:   创建TCP套接字
输入参数:   stTcpSock:TCP套接字结构体
输出参数:   stTcpSock:TCP套接字结构体
返 回 值:   成功返回RESULT_SUCCESS;失败返回RESULT_FAIL
*****************************************************************************************************/
LONG BuildTcpSocket(IO TCP_SOCKET_S* pstTcpSock)
{
    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_INFO, g_enDebugFlag, "Enter function BuildTcpSocket!");
    if(NULL == pstTcpSock)
    {
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                "BuildTcpSocket error, pstTcpSock is NULL");
        return RESULT_FAIL;
    }

    pstTcpSock->lTcpFd = socket(AF_INET, SOCK_STREAM, 0);
    if(RESULT_FAIL == pstTcpSock->lTcpFd)
    {
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, "Create TcpFd socket error!");
        return RESULT_FAIL;
    }

    if(RESULT_FAIL == SetTcpSockOpt(pstTcpSock->lTcpFd))
    {
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                    "Set socket option error, TcpFd = %ld!", pstTcpSock->lTcpFd);
        return RESULT_FAIL;
    }

    pstTcpSock->stSrvAddr.sin_family = AF_INET;
    pstTcpSock->stSrvAddr.sin_port = htons(SDK_SERVER_PORT);
    pstTcpSock->stSrvAddr.sin_addr.s_addr = htonl(INADDR_ANY);

    if(RESULT_FAIL == bind(pstTcpSock->lTcpFd, 
                            (struct sockaddr *)&(pstTcpSock->stSrvAddr), 
                            sizeof(pstTcpSock->stSrvAddr)))
    {
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                        "Bind socket error, TcpFd = %ld!", pstTcpSock->lTcpFd);
        close(pstTcpSock->lTcpFd);
        return RESULT_FAIL;
    }

    if(RESULT_FAIL == listen(pstTcpSock->lTcpFd, SDK_CLIENT_MAX_NUM))
    {
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                        "Listen socket error, TcpFd = %ld!", pstTcpSock->lTcpFd);
        close(pstTcpSock->lTcpFd);
        return RESULT_FAIL;
    }

    if(RESULT_FAIL == SetSockBlock(pstTcpSock->lTcpFd, FALSE))
    {
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                "SetNonBlock socket error, TcpFd = %ld!", pstTcpSock->lTcpFd);
        return RESULT_FAIL;
    }

    WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_INFO, g_enDebugFlag, 
            "Build TcpSocket success, TcpSocketFd = %ld!", pstTcpSock->lTcpFd);
    return RESULT_SUCCESS;
}

/****************************************************************************************************
函 数 名:   SetTcpSockOpt
功能描述:   设置TCP套接字属性
输入参数:   lTcpSockFd:套接字描述符
输出参数:
 返 回 值:   RESULT_SUCCESS 成功; RESULT_FAIL    失败
*****************************************************************************************************/
LONG SetTcpSockOpt(LONG lTcpSockFd)
{
    //setSendBufSize
    LONG lSendBufSize = DEFAULT_SENDRECV_SIZE;
    socklen_t lSendBufLength = sizeof(LONG);
    if(setsockopt((INT)lTcpSockFd, SOL_SOCKET, SO_SNDBUF, (CHAR*)&lSendBufSize,
        lSendBufLength) < 0)
    {
        (VOID)close((INT)lTcpSockFd);
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                                "SetTcpSockOpt SendBufSize error(%d)",  errno);
        return RESULT_FAIL;
    }

    //setRecBufSize
    LONG lRecvBufSize = DEFAULT_SENDRECV_SIZE;
    socklen_t lRecvBufLength = sizeof(LONG);
    if(setsockopt((INT)lTcpSockFd, SOL_SOCKET, SO_RCVBUF, (CHAR*)&lRecvBufSize,
        lRecvBufLength) < 0)
    {
        (VOID)close((INT)lTcpSockFd);
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                                "SetTcpSockOpt RecvBufSize error(%d)",  errno);
        return RESULT_FAIL;
    }

    LONG lDelayFlag = 1;
    if(setsockopt((INT)lTcpSockFd, IPPROTO_TCP, TCP_NODELAY, (CHAR*)&lDelayFlag,
        sizeof(lDelayFlag)) < 0)
    {
        (VOID)close((INT)lTcpSockFd);
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                                "SetTcpSockOpt TCP_NODELAY error(%d)",  errno);
        return RESULT_FAIL;
    }

    //setReuseAddr();
    LONG lReuseAddrFlag = 1;
    if(setsockopt((INT)lTcpSockFd, SOL_SOCKET, SO_REUSEADDR, (CHAR*)&lReuseAddrFlag,
        sizeof(lReuseAddrFlag)) < 0)
    {
        (VOID)close((INT)lTcpSockFd);
        WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag, 
                                "SetTcpSockOpt SO_REUSEADDR error(%d)",  errno);
        return RESULT_FAIL;
    }

    return RESULT_SUCCESS;
}

/****************************************************************************************************
函 数 名:   SetSockBlock
功能描述:   设置套接字为阻塞/非阻塞模式
输入参数:   iSocketFd:文件描述符; bBlocked :TRUE阻塞,FALSE非阻塞
返 回 值:   RESULT_SUCCESS 成功; RESULT_FAIL    失败
*****************************************************************************************************/
LONG SetSockBlock(LONG lTcpSockFd, BOOL bBlocked)
{
    if (bBlocked)
    {
        //设置为阻塞模式
        if (fcntl(lTcpSockFd, F_SETFL, fcntl(lTcpSockFd, F_GETFL & (~O_NONBLOCK))) < 0)
        {
            WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,
                                "fcntl client socket block error(%d)", errno);

            (VOID) close((INT) lTcpSockFd);
            return RESULT_FAIL;
        }
    }
    else
    {
        //设置为非阻塞
        if (fcntl(lTcpSockFd, F_SETFL, fcntl(lTcpSockFd, F_GETFL) | O_NONBLOCK) < 0)
        {
            WRITE_LOG(LOG_TYPE_DEBUG, LOG_LEVEL_ERR, g_enDebugFlag,
                            "fcntl client socket nonblock error(%d)", errno);

            (VOID) close((INT) lTcpSockFd);
            return RESULT_FAIL;
        }
    }

    return RESULT_SUCCESS;
}

posted on 2012-11-01 14:22  xuejianhui  阅读(275)  评论(0编辑  收藏  举报