c++ socket通信

socket通信是支持域名发送的,但是不能直接用域名发送,需要先解析域名,获取到实际IP地址才可以。

int SendMsg(char *szMsg, int nMsgLen)
{
    int nRet = 0;
    if(strlen(m_szIp) <= 0)
        return -1;

    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
    if (iResult != NO_ERROR)
        return -1;

    m_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(INVALID_SOCKET == m_sock)
    {
        WSACleanup();
        return -1;
    }
    SOCKADDR_IN  saddr;

    if (NULL == strstr(m_szIp, "com"))
    {
        saddr.sin_addr.S_un.S_addr = inet_addr(m_szIp);
    }
    else
    {
        struct hostent *hptr = NULL;

        if (NULL == (hptr = gethostbyname(m_szIp)))
        {
            return 1;
        }

        CopyMemory(&saddr.sin_addr.S_un.S_addr, hptr->h_addr_list[0], hptr->h_length);

        printf("hptr->h_addr_list[0]  = %s\n", hptr->h_addr_list[0]);

    }

    saddr.sin_family = AF_INET; 
    saddr.sin_port = htons((WORD)m_port);

// set the socket in non-blocking
    unsigned long mode = 1;
    int result = ioctlsocket(m_sock, FIONBIO, &mode);
    if (result != NO_ERROR) 
        printf("ioctlsocket failed with error: %ld\n", result);


     printf("connect start...");
    nRet = connect(m_sock, (const sockaddr *)&saddr, sizeof(SOCKADDR_IN));
     printf("connect finish...");

    // restart the socket mode
    mode = 0;
    result = ioctlsocket(m_sock, FIONBIO, &mode);
    if (result != NO_ERROR)
         printf("ioctlsocket failed with error: %ld\n", result);

    fd_set Write;
    FD_ZERO(&Write);
    FD_SET(m_sock, &Write);


    // check if the socket is ready
    TIMEVAL timeval = {0};
    timeval.tv_sec = 3;
    timeval.tv_usec = 0;

     printf("select start...");
    int selectresult = select(0, NULL, &Write, NULL, &timeval);
     printf("select finish.");

    switch (selectresult)
    {
    case -1: 
        return R_FAILURE;
    case 0 : //超时
        return R_FAILURE;
    default: //读就绪
        break; 
    }

    if(!FD_ISSET(m_sock, &Write))
    {
         printf("FD_ISSET error.");
        return S_FALSE;
    }

     printf("send start...");

    setsockopt(m_sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeval, sizeof(timeval));

    nRet = send(m_sock, szMsg, nMsgLen, 0);

     printf("send finish.");

    return S_OK;
}

int RecvMsg(std::string &srecv, int timeout/*=3*/)
{
    struct timeval Timeout;
    fd_set    rfds;
    int    nfds, selectresult;
    char buff[4097] = {0};
    int buffLen = 4096;
    int rest = buffLen, done = 0, recvbytes;

    int nlen = 0;
    //设置超时时间
    Timeout.tv_sec = timeout;
    Timeout.tv_usec = 0;

#ifndef _MSC_VER
    nfds = getdtablesize();
#else
    nfds = 0;
#endif

    FD_ZERO(&rfds);
    FD_SET(m_sock, &rfds);

    if(timeout < 0)
        selectresult = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, NULL);
    else
        selectresult = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, &Timeout);

    switch (selectresult)
    {
    case -1: 
        return R_FAILURE;
    case 0 : //超时
        return R_FAILURE;
    default: //读就绪
        break; 
    }
    while(recvbytes = recv(m_sock, buff, rest, 0))
    {    
        if(recvbytes == -1)
        {
            return R_FAILURE;
        }
        if(recvbytes < 0)
        {
            //接收异常
            return R_FAILURE;
        }

        if(recvbytes ==0)
        {
            //连接被对端关闭
            return (recvbytes);
        }

        srecv +=buff;
        done += recvbytes;
        memset(buff,0,4097);
        if(recvbytes == 4096)
        {
            continue;
        }
        //select again
        Timeout.tv_sec = 0;
        Timeout.tv_usec = 500000; /* 0.5 sec */
        if(timeout < 0)
            selectresult = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, NULL);
        else
            selectresult = select(nfds, &rfds, (fd_set*)0, (fd_set*)0, &Timeout);

        switch (selectresult)
        {

        case -1:
            return done;
        case 0 : //超时
            return done;
        default: //读就绪
            break; 
        }
    }
    return (done + recvbytes);
}

猜你喜欢

转载自blog.csdn.net/struborn_b/article/details/107385735