关于socket的connect超时的问题

关于socket的connect超时的问题


  1. timeval tm;  
  2. fd_set set;  
  3. unsigned long ul = 1;  
  4. ioctlsocket(sock, FIONBIO, &ul); //设置为非阻塞模式  
  5. bool ret = false;  
  6. if (connect(...) == -1)  
  7. {  
  8.     tm.tv_set  = TIME_OUT_TIME;  
  9.     tm.tv_uset = 0;  
  10.     FD_ZERO(&set);  
  11.     FD_SET(sock, &set);  
  12.   
  13.     if (select(sock, NULL, &set, NULL, &tm) > 0)  
  14.     {  
  15.         getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);  
  16.         if (error == 0)  
  17.         {  
  18.             ret = true;  
  19.         }  
  20.         else  
  21.         {  
  22.             ret = false;  
  23.         }  
  24.     }  
  25.     else  
  26.     {  
  27.         ret = false;  
  28.     }  
  29. }  
  30. else  
  31. {  
  32.     ret = true;  
  33. }  
  34. ul = 0;  
  35. ioctlsocket(sock, FIONBIO, &ul); //设置为阻塞模式  
  36. if(!ret)   
  37. {  
  38.     close( sockfd );  
  39.     printf(stderr , "Cannot Connect the server!/n");  
  40.     return;  
  41. }  
  42. printf( stderr , "Connected!/n");  

代码思路:  数据库

1.创建socket
 2
.将该socket设置为非阻塞模式
 3
.调用connect()
 4
.使用select()检查该socket描述符是否可写 多线程

 5.根据select()返回的结果判断connect()结果
 6
.将socket重设置为阻塞模式 app

 

所谓阻塞函数,是指其完成指定的任务以前不容许程序调用另外一个函数,在Windows下还会阻塞本线程消息的发送。 异步

所谓非阻塞函数,是指操做启动以后,若是能够当即获得结果就返回结果,不然返回表示结果须要等待的错误信息,不等待任务完成函数就返回。 socket

首先,异步函数是非阻塞函数; 函数

其次,获取远地信息的数据库函数是阻塞函数(所以,WinSock提供了其异步版本); spa

下面对具体函数作解释: .net

[cpp]  view plain copy
  1. int select(  
  2.   __in          int nfds,//本参数忽略,仅起到兼容做用  
  3.   __in_out      fd_set* readfds,//指向一组等待可读性检查的套接口,可为NULL  
  4.   __in_out      fd_set* writefds,//指向一组等待可写性检查的套接口,可为NULL  
  5.   __in_out      fd_set* exceptfds,//指向一组等待错误检查的套接口,可为NULL  
  6.   __in          const struct timeval* timeout//select()最多等待时间,对阻塞操做则为NULL  
  7. );  
  8.   
  9.   
  10.    

 

 本函数用于肯定一个或多个套接口的状态。对每个套接口,调用者可查询它的可读性、可写性及错误状态信息。用fd_set结构来表示一组等待检查的套接口 线程

 readfds参数标识等待可读性检查的套接口。若是该套接口正处于监听listen()状态,则如有链接请求到达,该套接口便被标识为可读,这样一个accept()调用保证能够无阻塞完成。对其余套接口而言,可读性意味着有排队数据供读取。或者对于SOCK_STREAM类型套接口来讲,相对于该套接口的虚套接口已关闭,因而recv()或recvfrom()操做均能无阻塞完成 server

writefds参数标识等待可写性检查的套接口。若是一个套接口正在connect()链接(非阻塞),可写性意味着链接顺利创建。若是套接口并未处于connect()调用中,可写性意味着send()和sendto()调用将无阻塞完成。〔但并未指出这个保证在多长时间内有效,特别是在多线程环境中〕。

exceptfds参数标识等待带外数据存在性或意味错误条件检查的套接口。请注意若是设置了SO_OOBINLINE选项为假FALSE,则只能用这种方法来检查带外数据的存在与否。对于SO_STREAM类型套接口,远端形成的链接停止和KEEPALIVE错误都将被做为意味出错。若是套接口正在进行链接connect()(非阻塞方式),则链接试图的失败将会表如今exceptfds参数中。

返回值:    select()调用返回处于就绪状态而且已经包含在fd_set结构中的描述字总数;若是超时则返回0;不然的话,返回SOCKET_ERROR错误,应用程序可经过WSAGetLastError()获取相应错误代码。

相关文章
相关标签/搜索