- 论坛徽章:
- 0
|
1.connect函数原型:
#include sys/types.h> /* See NOTES */
#include sys/socket.h>
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
RETURN VALUE:
If the connection or binding succeeds, zero is returned. On error, -1 is returned, and errno is set appropriately.
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.h>
#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 time = 1 + 2 + 4 + 8 + 18 + ... + 64 = 2^7 - 1 = 127 (s)
***/
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 \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。
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/105349/showart_2092919.html |
|