windows下设置socket的connect超时

    SOCKET Open(const char* strIP, UINT nPort, int nTimeOut)
    {
        SOCKET sockfd = NULL;
        
        do
        {
            sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
            if (sockfd <= 0)
            {
                printf("socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) error=%d ", WSAGetLastError());
                break;
            }

            unsigned long opt = 1;
            //set non-blocking
            if (ioctlsocket(sockfd, FIONBIO, &opt) < 0)
            {            
                printf("ioctlsocket(FIONBIO, %d) error=%d ", opt, WSAGetLastError());
                break;
            }
                    
            struct sockaddr_in serv_addr;
            
            //以服务器地址填充结构serv_addr
            serv_addr.sin_family = AF_INET;
            serv_addr.sin_addr.s_addr = inet_addr(strIP);
            serv_addr.sin_port = htons(nPort);

            if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(struct sockaddr)) == -1)
            {
                if (WSAGetLastError() == WSAEWOULDBLOCK)
                {
                    int error = -1;
                    int len = sizeof(int);

                    timeval tv_timeout;
                    tv_timeout.tv_sec  = 0;
                    tv_timeout.tv_usec = nTimeOut * 1000;

                    fd_set set;
                    FD_ZERO(&set);
                    FD_SET(sockfd, &set);

                    if (select(sockfd + 1, NULL, &set, NULL, &tv_timeout) > 0)
                    {
                        getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&error, &len);
                        if(error != 0)
                        {
                            break;
                        }
                    }
                    else
                    { //timeout or select error
                        break;
                    }
                }
                else
                {
                    printf("connect() error=%d ", WSAGetLastError());
                    break;
                }
            }

            
            opt = 0;
            //set blocking
            if (ioctlsocket(sockfd, FIONBIO, &opt) < 0)
            {
                printf("ioctlsocket(FIONBIO, %d) error=%d", opt, WSAGetLastError());
                break;
            }

            int iTimeOut = nTimeOut;
            setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeOut, sizeof(iTimeOut));        
            setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&iTimeOut, sizeof(iTimeOut));    

            return sockfd;
        }
        while (FALSE);
        
        closesocket(sockfd);
        return NULL;
    }

用于connect超时控制。

还有不完善的地方。

高手路过,请不吝赐教。

原文地址:https://www.cnblogs.com/vc60er/p/3156319.html