1. 程式人生 > >linux下socket connect超時設定

linux下socket connect超時設定


[From]http://www.ycgczj.com.cn/34733.html
網路程式設計中socket的分量我想大家都很清楚了,socket也就是套介面,在套介面程式設計中,提到超時的概念,我們一下子就能想到3個:傳送超時,接收超時,以及select超時(注: select函式並不是只用於套介面的,但是套介面程式設計中用的比較多),在connect到目標主機的時候,這個超時是不由我們來設定的。不過正常情況下這個超時都很長,並且connect又是一個阻塞方法,一個主機不能連線,等著connect返回還能忍受,你的程式要是要試圖連線多個主機,恐怕遇到多個不能連線的主機的時候,會塞得你受不了的。我也廢話少說,先說說我的方法,如果你覺得你已掌握這種方法,你就不用再看下去了,如果你還不瞭解,我願意與你分享。本文是已在Linux下的程式為例子,不過拿到Windows中方法也是一樣,無非是換幾個函式名字罷了。
Linux中要給connect設定超時,應該是有兩種方法的。一種是該系統的一些引數,這個方法我不講,因為我講不清楚:P,它也不是程式設計實現的。另外一種方法就是變相的實現connect的超時,我要講的就是這個方法,原理上是這樣的:
1.建立socket
2.將該socket設定為非阻塞模式
3.呼叫connect()
4.使用select()檢查該socket描述符是否可寫(注意,是可寫)
5.根據select()返回的結果判斷connect()結果
6.將socket設定為阻塞模式(如果你的程式不需要用阻塞模式的,這步就省了,不過一般情況下都是用阻塞模式的,這樣也容易管理)
如果你對網路程式設計很熟悉的話,其實我一說出這個過程你就知道怎麼寫你的程式了,下面給出我寫的一段程式,僅供參考。
/******************************
* Time out for connect()
* Write by Kerl W
******************************/
#include <sys/socket.h>
#include <sys/types.h>
#define TIME_OUT_TIME 20 //connect超時時間20秒
int main(int argc , char **argv)
{
  ………………
  int sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if(sockfd < 0) exit(1);
  struct sockaddr_in serv_addr;
  ………//以伺服器地址填充結構serv_addr
  int error=-1, len;
  len = sizeof(int);
  timeval tm;
  fd_set set;
  unsigned long ul = 1;
  ioctl(sockfd, FIONBIO, &ul); //設定為非阻塞模式
  bool ret = false;
  if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
  {
  tm.tv_set = TIME_OUT_TIME;
  tm.tv_uset = 0;
  FD_ZERO(&set);
  FD_SET(sockfd, &set);
  if( select(sockfd+1, NULL, &set, NULL, &tm) > 0)
  {
    getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
    if(error == 0) ret = true;
else ret = false;
  } else ret = false;
}
else ret = true;
ul = 0;
ioctl(sockfd, FIONBIO, &ul); //設定為阻塞模式
if(!ret)
{
close( sockfd );
fprintf(stderr , "Cannot Connect the server!n");
  return;
  }
fprintf( stderr , "Connected!n");
//下面還可以進行發包收包操作
……………
}