socket中connect的預設超時時間
1.connect函式原型:
|
2.預設情況下,connect函式的超時情況:
引用:
http://blog.chinaunix.net/u1/53217/showart_710651.html
《UNP》第一卷 第三版 P85-P86指出伯克利系統的超時時限為75s, Solaris9超時時限為4分鐘,所以一般認為是75s到幾分鐘不等,而我測試的時限為 189s(Linux Kernel 2.6.24),SYN6次重傳~~
我的FC8 Linux Kernel 2.6.23.1-42,測試超時時間為 189s
3.支援重試的連線(APUE2 16.4節)
#include
<
stdio.
#include
<
stdlib.
h>
#include
<
netinet/in
.
h>
#include
<
sys/socket.
h>
#include
<
string.
h>
#include
<
fcntl.
h>
#define SRV_PORT 65530
#define MAXSLEEP 128
#define errexit(
msg)
do {perror(
msg)
;
exit(
EXIT_FAILURE)
;
}
while
(
0)
/*
*
*
*
max sleep
*
*
*
/
int
connect_retry(
int
sockfd,
const struct
sockaddr *
srv_addr,
socklen_t addrlen)
{
int
nsec;
for
(
nsec =
1;
nsec <
=
MAXSLEEP;
nsec <
<
=
1)
{
if
(
connect(
sockfd,
srv_addr,
addrlen)
=
=
0)
return 0;
/*
connection accepted *
/
if
(
nsec <
=
MAXSLEEP / 2)
/*
<
=
2^7 /2 =
64*
/
sleep
(
nsec)
;
}
return -
1
}
int
main(
int
argc,
char *
argv[
]
)
{
int
sockfd;
struct
sockaddr_in srv_addr;
socklen_t addrlen;
int
flags;
if
(
argc !
=
2)
{
printf(
"Usage: %s <ip>/n"
,
argv[
0]
)
;
exit(
1)
;
}
if
(
(
sockfd =
socket(
AF_INET,
SOCK_STREAM,
0)
)
<
0)
errexit(
"socket error"
)
;
addrlen =
sizeof
(
struct
sockaddr)
;
memset(
&
srv_addr,
0,
addrlen)
;
srv_addr.
sin_family =
AF_INET;
srv_addr.
sin_addr.
s_addr =
inet_addr(
argv[
1]
)
;
srv_addr.
sin_port =
htons(
SRV_PORT)
;
flags =
fcntl(
sockfd,
F_GETFL,
0)
;
fcntl(
sockfd,
F_SETFL,
flags |
O_NONBLOCK)
;
printf(
"connecting.../n"
)
;
time_t t =
time(
NULL)
;
//if
(
connect(
sockfd,
(
struct
sockaddr *
)
&
srv_addr,
addrlen)
<
0)
{
if
(
connect_retry(
sockfd,
(
struct
sockaddr *
)
&
srv_addr,
addrlen)
<
0)
{
printf(
"interval = %d/n"
,
time(
NULL)
-
t)
;
close(sockfd);
errexit(
"connect error"
)
;
}
close(sockfd);
exit(
0)
;
}
說明:
1. 在阻塞情況下,connect函式在 Linux Kernel 2.6.23.1-42,測試超時時間為 189s。
2. 在用上述方法設定的非阻塞情況下,connect_retry 函式中,如果呼叫connect失敗,程序就會休眠一小段時間然後在嘗試連線,每迴圈一次增加每次嘗試的延遲, 直到最大延遲為 127s。