免费注册 查看新帖 |

Chinaunix

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

Linux网络编程 — 设置connect函数连接超时 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-08 17:44 |只看该作者 |倒序浏览
    最近在做一个在开发板启动后,程序运行前首先检查一下网络是否已经连通的东西。参考了网上的一些方法,现在整理一下。(使用system(ping IPaddress)也可以办到)
    其实问题的关键是,如何设置connect函数能够在指定的时间内返回。如果直接connect一个IP地址,不成功的话将会是一个漫长的等待时间。测试了一下2分钟内没有反映,但是网上有人说是75秒,还需要进一步确认啊!


过程如下:
    (1)调用fcntl,将socket置为非阻塞模式;
    (2)connect();
    (3)判断connect()的返回值,一般情况会返回-1,这时你还必须判断错误码如果是EINPROGRESS,那说明connect还在继续;如果错误码不是前者那么就是有问题了,不必往下执行,必须关掉socket;待下次重联;
    (4)select();设置好函数中的超时时间,将select()中的read和write置位,在超时时间内,如果select返回1,即描述字变为了可写,那么连接成功。 如果返回2,即描述字变为即可读又可写,那么出错。 如果返回0,那么超时。


代码如下:


#include stdio.h>
#include stdlib.h>
#include fcntl.h>
#include unistd.h>
#include sys/time.h>
#include sys/types.h>
#include netinet/in.h>
#include errno.h>
#define TIMEOUT 5
#define SERV_PORT 53
int main(int argc, char *argv[])
{
    if(argc != 2)
    {
        printf("Usage: client xxx.xxx.xxx.xxx\nExample: client 192.168.0.1\n");
        exit(1);
    }
    int sockfd, flags, res;
    struct sockaddr_in servaddr;
    fd_set fdr, fdw;
    struct timeval timeout;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd  0) {
        perror("Netwrok test...\n");
        return -1;
    }
    /* set socket fd noblock */
    if((flags = fcntl(sockfd, F_GETFL, 0))  0) {
        perror("Netwrok test...\n");
        close(sockfd);
        return -1;
    }
   
    if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK)  0) {
        perror("Network test...\n");
        close(sockfd);
        return -1;
    }
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    servaddr.sin_port = htons(SERV_PORT);
    if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
        if(errno != EINPROGRESS) {
// EINPROGRESS
            perror("Network test...\n");
            close(sockfd);
            return -1;
        }
    }
    else {
        printf("Connected\n");
        return 0;
    }
    FD_ZERO(&fdr);
    FD_ZERO(&fdw);
    FD_SET(sockfd, &fdr);
    FD_SET(sockfd, &fdw);
    timeout.tv_sec = TIMEOUT;
    timeout.tv_usec = 0;
    res = select(sockfd + 1, &fdr, &fdw, NULL, &timeout);
    if(res  0) {
        perror("Network test...\n");
        close(sockfd);
        return -1;
    }
    if(res == 0) {
        printf("Connect server timeout")
        close(sockfd);
        return -1;
    }
    if(res == 1) {
        if(FD_ISSET(sockfd, &fdw))
        {
            printf("Connected\n");
            close(sockfd);
            return 0;
        }
    }
    /* Not necessary */
    if(res == 2) {
        printf("Connect server timeout");
        close(sockfd);
        return -1;
    }
    printf("Connect server timeout");
    close(sockfd);
    return -1;
}




本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/88891/showart_1989918.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP