關於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()獲取相應錯誤代碼。

相關文章
相關標籤/搜索