select判断连接超时-来着gsoap

参考gsoap库

fd = (int)socket(AF_INET, SOCK_STREAM, 0);
if (soap->connect_timeout)
	fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)|O_NONBLOCK);
	
for (;;)
{ 
	//连接服务器失败
	if (connect((SOAP_SOCKET)fd, (struct sockaddr*)&sockaddr, sizeof(sockaddr)))
    { 
	  //如果设置了连接超时时间
      if (soap->connect_timeout && (soap_socket_errno == SOAP_EINPROGRESS 
		  || soap_socket_errno == SOAP_EWOULDBLOCK))
      { 
		struct timeval timeout;
        size_t n = sizeof(struct sockaddr_in);

        fd_set fds;
        if (soap->connect_timeout > 0)
        { timeout.tv_sec = soap->connect_timeout;
          timeout.tv_usec = 0;
        }
        else
        { timeout.tv_sec = -soap->connect_timeout/1000000;
          timeout.tv_usec = -soap->connect_timeout%1000000;
        }
        FD_ZERO(&fds);
        FD_SET((SOAP_SOCKET)fd, &fds);
		
		//select 当写事件发生或者超时事件发生则不在阻塞
		//如果超时则返回0
        for (;;)
        { 
			int r = select((SOAP_SOCKET)(fd + 1), NULL, &fds, NULL, &timeout);
			if (r > 0)
				break;
			if (!r)
			{ 
				soap->errnum = 0;
				DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Connect timeout\n"));
				soap_set_sender_error(soap, "Timeout", "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
				soap->fclosesocket(soap, (SOAP_SOCKET)fd);
				return SOAP_INVALID_SOCKET;
			}
			if (soap_socket_errno != SOAP_EINTR)
			{ 
				soap->errnum = soap_socket_errno;
				DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
				soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
				soap->fclosesocket(soap, (SOAP_SOCKET)fd);
				return SOAP_INVALID_SOCKET;
			}
        }
		
		//若无错误发生,getsockopt()返回0
		n = sizeof(soap->errnum);
        if (!getsockopt((SOAP_SOCKET)fd, SOL_SOCKET, SO_ERROR, (char*)&soap->errnum, &n) && !soap->errnum)
          break;
			
        soap->errnum = soap_socket_errno;
        soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
        soap->fclosesocket(soap, (SOAP_SOCKET)fd);
        return SOAP_INVALID_SOCKET;
      }
      else if (soap_socket_errno != SOAP_EINTR)
      { soap->errnum = soap_socket_errno;
        DBGLOG(TEST, SOAP_MESSAGE(fdebug, "Could not connect to host\n"));
        soap_set_sender_error(soap, tcp_error(soap), "TCP connect failed in tcp_connect()", SOAP_TCP_ERROR);
        soap->fclosesocket(soap, (SOAP_SOCKET)fd);
        return SOAP_INVALID_SOCKET;
      }
    }  
    else
      break;
}

//执行此次表示已经连接成功
if (soap->connect_timeout)
    	fcntl((SOAP_SOCKET)fd, F_SETFL, fcntl((SOAP_SOCKET)fd, F_GETFL)&~O_NONBLOCK);
	
soap->socket = fd;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ygmdream

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值