免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1584 | 回复: 0
打印 上一主题 下一主题

connect函数 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-11-12 18:40 |只看该作者 |倒序浏览

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
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP