zoukankan      html  css  js  c++  java
  • 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超时控制。

    还有不完善的地方。

    高手路过,请不吝赐教。

  • 相关阅读:
    P3970 [TJOI2014]上升子序列
    受欢迎的牛(Tarjan缩点模板)
    Y15BeTa的乱搞方法(占坑待填)
    Luogu P4145 上帝造题的七分钟2 / 花神游历各国
    Luogu P1525 【关押罪犯】
    Luogu P1077 摆花 NOIP2012pjT3
    Nowcoder deco的abs
    CSP-S前的芝士清单
    普天同庆
    线段树区改区查标记永久化板子
  • 原文地址:https://www.cnblogs.com/vc60er/p/3156319.html
Copyright © 2011-2022 走看看