目前各平台通用的設置套接字(Socket)連接超時的辦法是:
創建套接字,將其設置成非阻塞狀態。
調用connect連接對端主機,如果失敗,判斷當時的errno是否為EINPROGRESS,也就是說是不是連接正在進行中,如果是,轉到步驟3,如果不是,返回錯誤。
用select在指定的超時時間內監聽套接字的寫就緒事件,如果select有監聽到,證明連接成功,否則連接失敗。
以下是Linux
環境下的示例代碼:
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(int
argc, char *argv[])
{
int fd, retval;
struct sockaddr_in addr;
struct timeval timeo = {3,
0};
socklen_t len = sizeof(timeo);
fd_set
set;
fd
= socket(AF_INET, SOCK_STREAM, 0);
if (argc ==
4)
timeo.tv_sec = atoi(argv[3]);
fcntl(fd,
F_SETFL, fcntl(fd,
F_GETFL) | O_NONBLOCK);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(argv[1]);
addr.sin_port = htons(atoi(argv[2]));
printf("%d\n", time(NULL));
if (connect(fd,
(struct sockaddr*)&addr, sizeof(addr))
== 0)
{
printf("connected\n");
return 0;
}
if (errno !=
EINPROGRESS) {
perror("connect");
return -1;
}
FD_ZERO(&set);
FD_SET(fd,
&set);
retval
= select(fd + 1,
NULL, &set,
NULL, &timeo);
if (retval ==
-1) {
perror("select");
return -1;
} else if(retval ==
0) {
fprintf(stderr, "timeout\n");
printf("%d\n", time(NULL));
return 0;
}
printf("connected\n");
return 0;
}
[root@lanhai-Linux CONNI]#
./coni 10.16.101.1
90
1223898556
timeout
1223898559
[root@lanhai-Linux CONNI]# ./coni
10.16.101.1 90
1223898609
timeout
1223898612
[root@lanhai-Linux
CONNI]# ./coni 192.168.18.45
段錯誤
[root@lanhai-Linux CONNI]# ./coni
192.168.18.45 90
1223898767
[root@lanhai-Linux CONNI]#
./coni 192.168.18.37 80
1223898771
connected
[root@lanhai-Linux
CONNI]#