免费注册 查看新帖 |

Chinaunix

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

[网络] LINUX下TCP编程,如何设置TCP连接超过预计时间后自动断开? [复制链接]

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17操作系统版块每日发帖之星
日期:2016-06-12 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-05-12 21:49 |只看该作者 |倒序浏览
本帖最后由 mini_peng 于 2015-05-13 22:56 编辑

函数int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout);的最后一个参数,是起这个作用的吗?
比如:我想让TCP 某连接180秒内无数据传送(闲置)就超时自动断开。这个参数可以实现吗?

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17操作系统版块每日发帖之星
日期:2016-06-12 06:20:00
2 [报告]
发表于 2015-05-12 21:54 |只看该作者
struct timeval tv;

        tv.tv_sec = 30;
        tv.tv_usec = 0;
                nready = select(maxfd + 1, &rset, NULL, NULL, &tv);

似乎没见起作用,空闲40秒后,TCP连接依然存活。

论坛徽章:
1
射手座
日期:2013-11-07 09:19:48
3 [报告]
发表于 2015-05-13 13:17 |只看该作者
select不是做这个事的。
TCP有保活机制,即使TCP链接空闲,保活机制也可以保持链接一段时间,这个时间可以通过相关参数调整,由于这些参数都是全局性的,所以调整的时候需要考虑整个系统,而不仅仅是某一些应用。
针对你的问题,可以起个定时器,收到一个数据包就对定时器清零;当定时器到达30秒,断开TCP链接。

论坛徽章:
0
4 [报告]
发表于 2015-05-13 17:34 |只看该作者
select 只是查看在制定时间内是否有 fd 可读或可写
返回 0 超时的时候,你直接 close 这个socket 不就好了么?

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17操作系统版块每日发帖之星
日期:2016-06-12 06:20:00
5 [报告]
发表于 2015-05-13 22:54 |只看该作者
回复 4# Logic0

我等了很久,它都没有超时而断开。


   

论坛徽章:
0
6 [报告]
发表于 2015-05-14 15:52 |只看该作者
mini_peng 发表于 2015-05-13 22:54
回复 4# Logic0

我等了很久,它都没有超时而断开。


和你等多久没关系,编码要把自己的意图明白地写出来,不要期待其他人“自动”给你做什么
你想让它断开,就直接close

论坛徽章:
3
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17操作系统版块每日发帖之星
日期:2016-06-12 06:20:00
7 [报告]
发表于 2015-05-17 17:16 |只看该作者
本帖最后由 mini_peng 于 2015-05-17 17:17 编辑

回复 6# Logic0


    那我只好,另开一个线程,做一个死循环,读当前时间与 最近一次接收到数据时产生的时间标记 进行比较,然后close();

但,我不知道,另开一个线程做死循环,会不会对操作系统的响应上有很大影响 ??

论坛徽章:
0
8 [报告]
发表于 2015-05-18 17:00 |只看该作者
mini_peng 发表于 2015-05-17 17:16
回复 6# Logic0


不是这个意思,select 的作用是 在 timeout 指定时间内,观察 是否有指定的可读或可写事件发生,如果有发生则给出这个 fd,如果没有则返回0,也就是在timeout 事件内没有关注的事件发生;

链接是否有数据过来,是探测可读事件,timeout 事件内无可读事件,也就是 select 返回 0,你就直接调用 close ,关闭链接;

可写麻烦一些,可以给每个socket 绑定一个 计时器,过期关闭即可,无需定期扫描。不过定期扫描对大量 socket 来说,也不失为一种方案。

PS:在linux 下,可以使用 man + 命令 或者 man + 函数 的方式来查看这个命令或者系统调用的文档

论坛徽章:
0
9 [报告]
发表于 2015-06-16 18:05 |只看该作者
  1. res = select(read, wirte, error, time)
  2. if(res == 0 )
  3.   //如果在time时间内,没有动作,则关闭
  4.   close...
  5. else //有动作,检查,然后做事
  6.   do something
复制代码

论坛徽章:
1
2015亚冠之迪拜阿赫利
日期:2015-07-01 18:38:38
10 [报告]
发表于 2015-06-19 11:23 |只看该作者
  1. struct timeval tv;
  2. tv.tv_sec = 180;
  3. tv.tv_usec = 0;
  4. nready = select(maxfd + 1, &rset, NULL, NULL, &tv);
  5. if(nready<0)
  6. close(fd);//关掉你要关的socket fd
  7. else
  8. ...
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP