免费注册 查看新帖 |

Chinaunix

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

[C] connect超时怪问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-01-14 10:50 |只看该作者 |倒序浏览
开门见山吧,呵呵:  

硬件平台:ARM9   
软件平台:ECOS       网络协议栈(FreeBSD)   

问题描述:

    两块板卡,一块跑 TCP socket Server(accept),一块跑 TCP socket Client(connect),都接入大网环境中(同一层楼的局域网),一个专门发数据,一个专门收数据,通信时间只能连续持续几个小时,然后出现“Broken  Pipe”和“Connect  Reset  By  Peer”的错误,send、recv函数都返回-1退出了。接下来我就想当出现错误时在程序中让它们自动重连然后再收发,也就是 Client:先close(sk)、重新socket、connect,而Server端一直有个任务在accept,结果现象是,前面几次重连过程中Client都是要连好几次或十几次(中间有时间不等的延时)才能连上,到后来(几个小时后)两者就怎么也连不上了(TCP三次握手不成功),试过很多方法都不行(l_onoff=1; l_linger=0等等)。后来发现ecos下的connect为7秒超时,而抓包发现不管是ARP请求还是TCP SYN,双方的响应都很迟钝(不知为什么),十多秒后对方才reply是很经常的事,所以connect不上也很正常吧。

    那就更改connect的超时时间,通用的方法:设置非阻塞socket、connect、设置time、select.、判断可写否、getsockpot,但我发现time的值在7s以内都是生效的,大于7秒时,都是在7s的时候select返回,在ecos库中寻找相关线索也无果(可能是自己还不了解)   

    问题就是怎样让connect的超时时间大于7秒,大家帮忙讨论讨论吧...,看看有啥办法没,谢谢,我的代码如下:

  1.         int sk,ret;
  2.         struct timeval tv;
  3.         fd_set rdevents, wrevents;

  4.                 if ((sk=socket(AF_INET, SOCK_STREAM, 0))<0)
  5.                 {
  6.                          perror("Socket build fail\n");
  7.                          return        ERROR;
  8.                 }

  9.                 if( ioctl(sk,FIONBIO,&non_blocking) == -1 )
  10.                         perror("*********** ioctlsocket  ");

  11.                 ret = connect(sk, (struct sockaddr *)&destserver, sizeof(destserver));

  12.                 if ( 0 == ret)
  13.                 {
  14.                         printf("connect success...\n");
  15.                         ioctl(sk,FIONBIO,&blocking);
  16.                         break;
  17.                 }
  18.                 else if( (0 != ret) && (errno != EINPROGRESS) )
  19.                 {
  20.                         close(sk);
  21.                         perror("cannot conenct to server \n");
  22.                         continue;
  23.                 }
  24.                 else
  25.                 {
  26.                         FD_ZERO(&wrevents);
  27.                         FD_SET(sk, &wrevents);
  28.                         rdevents = wrevents;

  29.                         tv.tv_sec = 30;  //在这里设置connect的超时时间,但如果大于7就不起作用 !!!
  30.                         tv.tv_usec = 0;
  31.                                                //下面select总是在7秒内返回 !!!!!!!!
  32.                         ret = select(sk+1, (fd_set *)&rdevents, (fd_set *)&wrevents, (fd_set *)0, &tv);
  33.                         ……
  34.                 }
复制代码

论坛徽章:
39
2017金鸡报晓
日期:2017-02-08 10:39:4219周年集字徽章-周
日期:2023-04-15 12:02:2715-16赛季CBA联赛之深圳
日期:2023-02-16 14:39:0220周年集字徽章-年
日期:2022-08-31 14:25:28黑曼巴
日期:2022-08-17 18:57:0919周年集字徽章-年
日期:2022-04-25 13:02:5920周年集字徽章-20	
日期:2022-03-29 11:10:4620周年集字徽章-年
日期:2022-03-14 22:35:1820周年集字徽章-周	
日期:2022-03-09 12:51:3220周年集字徽章-年
日期:2022-02-10 13:13:4420周年集字徽章-周	
日期:2022-02-03 12:09:4420周年集字徽章-20	
日期:2022-01-25 20:14:27
2 [报告]
发表于 2008-01-14 11:42 |只看该作者
while(1) select();

论坛徽章:
0
3 [报告]
发表于 2008-01-14 16:45 |只看该作者
你服务端程序中listen()用的backlog参数是多少?

论坛徽章:
0
4 [报告]
发表于 2008-01-14 17:19 |只看该作者
谢谢大家。。。

因为每一次connect时,都要close再重新socket(否则报错),要想在7秒内连上每次的情况还是差不多啊,碰上那次运气好就连上了,所以while 1还是解决不了问题的 : (

backlog 5跟10都试过了,其实我现在就是一直在while 1 connect,抓包发现只是server的响应包回的太慢,而且一直只是这一个client在connect,每次connect间隔时间从1秒到120秒不等。

论坛徽章:
0
5 [报告]
发表于 2008-01-14 23:08 |只看该作者
if ( 0 == ret)
{
.....
}
else if( (0 != ret) && (errno != EINPROGRESS) )
{
...
}

你的判断代码不太合理

论坛徽章:
0
6 [报告]
发表于 2008-01-14 23:11 |只看该作者
有没有想过是你服务端程序的问题,我上面只是指出你的判断不太合理,与解决这个问题无关,呵呵

论坛徽章:
0
7 [报告]
发表于 2008-01-15 13:55 |只看该作者
呵呵,谢谢。我的服务器端程序很简单,一个线程阻塞地accept(非阻塞select也试过了),客户端连上后再开一线程专门收发(优先级略高),当收发出错后(总是略先于client出错),立刻删除此线程,重新只剩一个阻塞地accept,通过串口观察实际过程确实如此,因代码太简单了(基本和本问题关系不大),就不贴了。

论坛徽章:
0
8 [报告]
发表于 2008-01-16 20:15 |只看该作者
程序的判断是合理的,不过楼主的情况很诡异。

论坛徽章:
0
9 [报告]
发表于 2008-01-17 09:16 |只看该作者
呵呵,怪的都无语了,网上查遍了connect超时的问题,别人都千方百计地想缩短这超时时间,我却相反,哈哈

论坛徽章:
0
10 [报告]
发表于 2008-01-17 10:29 |只看该作者
记得看过这方面的资料,系统本身有一个超时,自己设置超时时,只有少于系统超时才有意义,否则就按照系统超时运行。
要更改这个,应该需要修改内核协议栈。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP