zoukankan      html  css  js  c++  java
  • [转]windows下设置socket的connect超时

    原文地址:http://www.cnblogs.com/BloodAndBone/archive/2012/05/22/2513338.html

    变相的实现connect的超时,我要讲的就是这个方法,原理上是这样的:
    1.建立socket
    2.将该socket设置为非阻塞模式
    3.调用connect()
    4.使用select()检查该socket描述符是否可写(注意,是可写)
    5.根据select()返回的结果判断connect()结果
    6.将socket设置为阻塞模式(如果你的程序不需要用阻塞模式的,这步就省了,不过一般情况下都是用阻塞模式的,这样也容易管理)

    // widonws: 默认设置socket TCP client connect为阻塞模式
    void TcpConnect(char* strIP, UINT nPort)
    {
        struct sockaddr_in serverAddress;
        SOCKET hSocket = NULL;
    
        hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if( hSocket==INVALID_SOCKET)
        {
            return;
        }
    
        memset(&serverAddress, 0, sizeof(serverAddress));     
        serverAddress.sin_family      = AF_INET;
        serverAddress.sin_addr.s_addr = inet_addr(strIP);   
        serverAddress.sin_port        = htons((short)nPort);      
        int iTimeOut = 3000;
        setsockopt(hSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&iTimeOut,sizeof(iTimeOut));
        setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&iTimeOut,sizeof(iTimeOut));    
    
        if( SOCKET_ERROR==connect(hSocket, (sockaddr*)&serverAddress, sizeof(serverAddress)) )
        {        
            closesocket(hSocket);
            DWORD gle = WSAGetLastError();
    
            return;
        }
    
        char buff[] = "hello";
        int sl=::send(hSocket,(char*)buff, sizeof(buff), 0);
        if( sl<0 )
        {
            closesocket(hSocket);
            return ;
        }
        closesocket(hSocket);
    }
    
    // widonws: 设置socket TCP client connect非阻塞模式
    void SockSelect(char* strIP, UINT nPort)
    {
        SOCKET/*int*/ sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if(sockfd < 0) 
        {
            return;
        }
        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);
        int error = -1;
        int len = sizeof(int);
        timeval tm;
        fd_set set;
        unsigned long ul = 1;
        ioctlsocket(sockfd, FIONBIO, &ul); //设置为非阻塞模式
        bool ret = false;
        if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
        {
            tm.tv_sec  = 3;
            tm.tv_usec = 0;
            FD_ZERO(&set);
            FD_SET(sockfd, &set);
            if( select(sockfd+1, NULL, &set, NULL, &tm) > 0)
            {
                getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *)&error, /*(socklen_t *)*/&len);
                if(error == 0) 
                    ret = true;
                else 
                    ret = false;
            } 
            else 
                ret = false;
        }
        else 
            ret = true;
        ul = 0;
        ioctlsocket(sockfd, FIONBIO, &ul); //设置为阻塞模式
        if(!ret) 
        {
            closesocket( sockfd );
            fprintf(stderr , "Cannot Connect the server!/n");
            return;
        }
    
        fprintf( stderr , "Connected!/n");
    
        char buff[] = "hello";
        int sl=::send(sockfd,(char*)buff, sizeof(buff), 0);
    
        closesocket( sockfd );
    }
    

      

  • 相关阅读:
    [ Openstack ] Openstack-Mitaka 高可用之 环境初始化
    [ Openstack ] OpenStack-Mitaka 高可用之 概述
    Swift
    Swift
    报错
    归并排序
    堆排序
    插入排序
    早睡早起身体好
    用于查询的日期类型转换帮助类
  • 原文地址:https://www.cnblogs.com/barrysgy/p/3640455.html
Copyright © 2011-2022 走看看