免费注册 查看新帖 |

Chinaunix

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

请教:如何解决connect长时间等待问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-12 16:41 |只看该作者 |倒序浏览
在做tcp程序时,使用connect和不存在的服务器(服务器未启动)进行连接的时候,总要等待几秒钟时间,能不能让其马上返回

论坛徽章:
0
2 [报告]
发表于 2005-11-12 17:11 |只看该作者
不可以的!
如果马上返回,没有测试联接呢?
也许网速慢呢?
都要考虑的!

论坛徽章:
0
3 [报告]
发表于 2005-11-12 23:36 |只看该作者
用Non-blocking模式

论坛徽章:
0
4 [报告]
发表于 2005-11-14 09:23 |只看该作者

No_BLOCKING方式不行

我在程序中使用IOCTL的NO_BLOCKING方式即使存在的主机也不能连接

论坛徽章:
0
5 [报告]
发表于 2005-11-14 09:27 |只看该作者
用fcntl呢,设置成非阻塞

论坛徽章:
0
6 [报告]
发表于 2005-11-14 09:50 |只看该作者
1.首先用设置Non-blocking
2.调用connect,这时会立即返回
3.设置一个超时struct timeval tv;
tv.tv_sec =5; //wait for 5s
用select.(s,...&tv)

论坛徽章:
0
7 [报告]
发表于 2005-11-14 10:55 |只看该作者

不能使用select

select函数监测的是已经连接的端口,在connect中,直接返回时,返回的是错误-1,所以这里不能用这种方法

论坛徽章:
0
8 [报告]
发表于 2005-11-14 13:06 |只看该作者
非阻塞connect实现:

在阻塞套接字的一般情况下,connect ()直到客户端对SYN消息的ACK消息到达之前才会返回。使connect()调用具有超时机制的一个方法是让套接字成为非阻塞的套接字体,然后用select()来等待它完成。
代码:

s = socket(AF_INET, SOCK_STREAM, 0);
//下面获取套接字的标志
if ((flags = fcntl(s, F_GETFL, 0)) < 0) {
    //错误处理
}

//下面设置套接字为非阻塞
if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
    //错误处理
}

if ((retcode = connect(s, (struct sockaddr*)&peer, sizeof(peer)) &&
    errno != EINPROGRESS) {
   //因为套接字设为NONBLOCK,通常情况下,连接在connect()返回
   //之前是不会建立的,因此它会返回EINPROGRESS错误,如果返回
   //任何其他错误,则要进行错误处理
}

if (0 == retcode) {  //如果connect()返回0则连接已建立
    //下面恢复套接字阻塞状态
    if (fcntl(s, F_SETFL, flags) < 0) {
        //错误处理
    }

    //下面是连接成功后要执行的代码
   
    exit(0)
}

FD_ZERO(&rdevents);
FD_SET(s, &rdevents);  //把先前的套接字加到读集合里面
wrevents = rdevents;   //写集合
exevents = rdevents;   //异常集合

tv.tv_sec = 5;  //设置时间为5秒
tv_tv_usec = 0;

retcode = select(s+1, &rdevents, &wrevents, &exevents, &tv);
if (retcode < 0) {  //select返回错误???
    //错误处理
}
else if (0 == retcode) {  //select 超时???
    //超时处理
}
esle {
    //套接字已经准备好
    if (!FD_ISSET(s, &rdevents) && !FD_ISSET(s, &wrevents)) {
        //connect()失败,进行错处理
    }

    if (getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
        //getsockopt()失败,进行错处理
    }

    if (err != 0) {
        //connect()失败,进行错处理
    }

    //到这里说明connect()正确返回
    //下面恢复套接字阻塞状态
    if (fcntl(s, F_SETFL, flags) < 0) {
        //错误处理
    }

    //下面是连接成功后要执行的代码
   
    exit(0)
}

论坛徽章:
0
9 [报告]
发表于 2005-11-14 13:26 |只看该作者
写得好呀,谢谢

论坛徽章:
0
10 [报告]
发表于 2005-11-17 15:11 |只看该作者

谢谢,采用多线程

楼上些得很清楚明了,但使用select的话还是需要等待,时间长了会影响效率,短了连接成功率太低,我现在的做法是,采用多线程,其中一个线程连接,另一个线程使用
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP