首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >TCP的KeepAlive探测详解

TCP的KeepAlive探测详解

作者头像
glinuxer
发布于 2019-04-10 06:56:44
发布于 2019-04-10 06:56:44
5.6K0
举报
文章被收录于专栏:专注网络研发专注网络研发

在写TCP服务程序时,除了要处理SIGPIPE外,还要有客户端连接检测机制,用于及时发现崩溃的客户端连接。一般来说,有两种检测方式:1. 在应用层,由业务程序自己检测;2. 使用TCP的KeepAlive机制。

使用第一种方式,意味着要在应用层自己实现一个ping-pong逻辑和协议,并支持设置空闲时长,重试次数,重试间隔等。这无疑会增加一定的代码量,好处则是可以自己控制逻辑,同时不用学习内核的实现:)

但是如果没有特殊的需求,我更倾向于第二种方式。如非必要,不要引入额外的逻辑。更何况既然TCP本身已经支持KeepAlive,为什么还要自己实现一套,多此一举呢?代码写的越多,越可能引入Bug:D

本文将对TCP的KeepAlive的使用和原理做比较详细的分析。先看如何使用TCP KeepAlive来检测“失联”的TCP连接。完整的测试代码位于:https://github.com/gfreewind/LinuxDetails/blob/master/networks/6.tcp_keepalive_reporter/tcp_keepalive_report.c。

本文只截图几个关键的函数

其中SO_KEEPALIVE用于打开或者关闭KeepAlive功能,TCP_KEEPIDLE用于设置空闲时间——即有多久没有发送报文就进行探测,TCP_KEEPCNT用于设置KeepAlive的尝试次数,TCP_KEEPINTVL用于设置重试KeepAlive的报文间隔。这里容易搞混的是TCP_KEEPIDLE和TCP_KEEPINTVL,前者是需要进行KeepAlive探测的空闲时间,而后者是在某次KeepAlive探测失败,再次重试的间隔时间。对于上面的程序来说,当该TCP连接有5秒没有进行数据传输时,就会发送KeepAlive探测报文。当探测报文失败时,会隔2秒再次发送探测报文,3次探测失败就判断连接失败。

通过测试程序,我们可以使用tcpdump抓包,来分析KeepAlive。

前三个报文是TCP的三次握手,连接成功后,没有任何报文发送。间隔5秒后,发送KeepAlive,即第4个报文。第5个报文为KeepAlive ACK。再间隔5秒后,再次发送KeepAlive探测报文,即第6个报文。

(请忽略报文的黑颜色,因为这个测试是本机发给本机,所以TCP校验和是不正确的——没有真正通过网卡)

为了测试KeepAlive检测报文失败的情况,在连接成功之后,我使用iptables创建一条规则,丢弃发往port 34567端口的数据报文。这时抓包结果如下:

同上,前三个报文完成TCP三次握手,间隔5秒后发送KeepAlive探测报文,但由于没有收到ACK,所以每间隔2秒再次发送KeepAlive,重试3次后,判定连接失败,在11秒时(应该发送第4个KeepAlive时)发送RST给对端,中断连接。

那么当KeepAlive机制判断连接崩溃时,应用层如何得到通知呢?当连接正常关闭时,应用层可以得到可读事件通知,并且进行read操作时,返回结果为0——这也是服务端判断客户端关闭连接的方法。就此推测,KeepAlive机制判断连接崩溃时,其行为应该与正常关闭类似。在测试代码中,分别使用了select和epoll来进行io事件测试,其输出如下:

根据测试,无论是使用select还是epoll,当KeepAlive中止连接时,应用层都可以得到可读事件通知,并且read结果为0。上面的输出,还有一个sock err is 110的结果。这是另外一种判断机制:

当KeepAlive中断连接时,其会设置socket错误,应用层通过getsockopt即SO_ERR可以获得该错误。

通过测试程序,我们只是学到了KeepAlive的使用方法。接下来就要进入内核对KeepAlive一探究竟。

tcp_keepalive_timer为KeepAlive定时器的回调函数。在这个函数中

当探测超时,就会调用tcp_send_active_reset向对端发送RST报文,中止连接,然后调用tcp_write_err。

设置sk->sk_err等于ETIMEOUT,其值就是测试程序打印的110。而sk_error_report指向的是sock_def_error_report。

其会唤醒等待在当前套接字的进程,且其IO事件是POLLERR。

而在使用epoll_ctl添加监听fd时,内核会自动把EPOLLERR和EPOLLHUP加到监听事件中。这就是为什么epoll可以得到通知。

至此,我们已经从实现和使用上,完成了对TCP KeepAlive机制的探索。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LinuxerPub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
TCP keepalive特性解析
TCP keepalive机制最初是为了解决长时间处于空闲状态的连接问题而设计的。
zenlu
2024/02/21
8290
TCP keepalive特性解析
心跳包机制设计详解
情形一:一个客户端连接服务器以后,如果长期没有和服务器有数据来往,可能会被防火墙程序关闭连接,有时候我们并不想要被关闭连接。例如,对于一个即时通讯软件,如果服务器没有消息时,我们确实不会和服务器有任何数据交换,但是如果连接被关闭了,有新消息来时,我们再也没法收到了,这就违背了“即时通讯”的设计要求。
范蠡
2019/08/09
7.3K0
分析 HTTP,TCP 的长连接和短连接以及 sock
HTTP 的长连接和短连接本质上是 TCP 长连接和短连接。HTTP 属于应用层协议,在传输层使用 TCP 协议,在网络层使用 IP 协议。IP 协议主要解决网络路由和寻址问题,TCP 协议主要解决如何在 IP 层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP 有可靠,面向连接的特点。
杰哥的IT之旅
2020/06/18
5.1K0
分析 HTTP,TCP 的长连接和短连接以及 sock
套接字连接状态检测
主动断开连接 主动断开连接会发送,关闭事件 connec函数检测连接状态,getlasterror send发送(tcp keeplive心跳包或者有数据时检测),recv接收判断异常(无数据判断异常) linux中的 select(socket用户和内核传递数组,大小有限制) poll(同select大小无限制,链表维护) epoll(内核态数据) 拔网线 拔网线后,关闭事件不能传递,连接状态不好检测 设置连接或者发送超时,同步套接字超时设置 // platform-specific switch #i
sofu456
2021/12/06
1.2K0
不为人知的网络编程(十二):彻底搞懂TCP协议层的KeepAlive保活机制
文中引用了参考资料中的部分内容,本文参考资料详见文末“参考资料”一节,感谢资料分享者。
JackJiang
2021/04/19
1.3K0
通过linux源码分析nodejs的keep-alive
之前已经分析过了keep-alive,最近在使用nodejs的keep-alive的时候发现了遗漏了一个内容。本文进行一个补充说明。我们先看一下nodejs中keep-alive的使用。
theanarkh
2020/06/28
1.1K0
又见KeepAlive
最近工作中遇到一个问题,想把它记录下来,场景是这样的: 从上图可以看出,用户通过Client访问的是LVS的VIP, VIP后端挂载的RealServer是Nginx服务器。 Client可以是浏览器
小小科
2018/05/04
1.8K0
又见KeepAlive
通过源码理解http层和tcp层的keep-alive
很久没更新文章了,今天突然想到这个问题,打算深入理解一下。我们知道建立tcp连接的代价是比较昂贵的,三次握手,慢开始,或者建立一个连接只为了传少量数据。这时候如果能保存连接,那会大大提高效率。下面我们通过源码来看看keep-alive的原理。本文分成两个部分
theanarkh
2020/06/19
8890
TCP协议详解-定时器
        如代码所示,如果tcp的state<ESTABLISHED,表明其处于连接建立状态。定时器超时后,调用dropit终止连接。大多数伯克利系统将建立一个连接的最长时间设置为75s。连接建立定时器配合重传定时器一起使用,重传定时器会隔一段时间重传SYN,如下图所示:
无毁的湖光-Al
2018/08/14
7950
TCP协议详解-定时器
TCP 的 Keepalive 和 HTTP 的 Keep-Alive 是一个东西吗?
HTTP 的 Keep-Alive,是由应用层(用户态) 实现的,称为 HTTP 长连接; TCP 的 Keepalive,是由 TCP 层(内核态) 实现的,称为 TCP 保活机制;
IT运维技术圈
2022/10/24
1.5K0
qtcpsocket 客户端_qtcpsocket接收结构体数据
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/09/30
1.4K0
nginx keepalive_timeout 设置策略问题分析
1.项目环境:nginx(前段代理,仅作代理用途)+3个tomcat(都在同一个服务器上),做的web项目 2.涉及到的业务逻辑:文件上传(可能有大文件,比如说android游戏,100m);客户端接口请求;网站后台管理 3.问题重现流程: 3.1 配置好tomcat后,直接加上nginx前段代理(仅配置了http代理) 3.2 问题一:当管理员后台上传文件时,大文件无法上传成功,出现time-out,经重复测试,发现上传时间超过1分钟以后,就会返回超时信息,小文件没有问题 3.2 经调研得知ng
老七Linux
2018/05/31
4.1K0
字节一面:服务端挂了,客户端的 TCP 连接还在吗?
收到一位读者的私信,说字节面试有这么一个问题:服务端挂了,客户端的 TCP 连接会发生什么?
愿天堂没有BUG
2022/09/12
2.3K0
TCP漫谈-之keepalive和time_wait
TCP是一个有状态通讯协议,所谓的有状态是指通信过程中通信的双方各自维护连接的状态。
宜信技术学院
2020/04/09
2.2K0
TCP漫谈-之keepalive和time_wait
4个实验,彻底搞懂TCP连接的断开
看到这个标题你可能会说,TCP 连接的建立与断开,这个我熟,不就是三次握手与四次挥手嘛。且慢,脑海中可以先尝试回答这几个问题:
龟仙老人
2021/10/26
4.8K0
TCP连接的状态详解以及故障排查
linux查看tcp的状态命令: 1)、netstat -nat 查看TCP各个状态的数量 2)、lsof -i:port 可以检测到打开套接字的状况 3)、 sar -n SOCK 查看tcp创建的连接数 4)、tcpdump -iany tcp port 9000 对tcp端口为9000的进行抓包 5)、tcpdump dst port 9000 -w dump9000.pcap 对tcp目标端口为9000的进行抓包保存pcap文件wireshark分析。 6)、tcpdump tcp port 9000 -n -X -s 0 -w tcp.cap 对tcp/http目标端口为9000的进行抓包保存pcap文件wireshark分析。
黄规速
2022/04/15
3.9K0
TCP连接的状态详解以及故障排查
TCP连接的状态详解以及故障排查
我们通过了解TCP各个状态,可以排除和定位网络或系统故障时大有帮助。(总结网络上的内容)
Java架构师历程
2018/09/26
6.7K0
TCP连接的状态详解以及故障排查
linux服务器开发三(网络编程) --二
半关闭 当TCP链接中A发送FIN请求关闭,B端回应ACK后(A端进入FIN_WAIT_2状态),B没有立即发送FIN给A时,A方处在半链接状态,此时A可以接收B发送的数据,但是A已不能再向B发送数据。 从程序的角度,可以使用API来控制实现半连接状态。 #include <sys/socket.h> int shutdown(int sockfd, int how); sockfd: 需要关闭的socket的描述符 how: 允许为shutdown操作选择以下几种方式: SHUT
李海彬
2018/03/27
2.5K0
linux服务器开发三(网络编程) --二
不为人知的网络编程(十四):拔掉网线再插上,TCP连接还在吗?一文即懂!
说到TCP协议,对于从事即时通讯/IM这方面应用的开发者们来说,再熟悉不过了。随着对TCP理解的越来越深入,很多曾今碰到过但没时间深入探究的TCP技术概念或疑问,现在是时候回头来恶补一下了。
JackJiang
2022/03/09
1.3K0
不为人知的网络编程(十四):拔掉网线再插上,TCP连接还在吗?一文即懂!
聊聊 TCP 长连接和心跳那些事
可能很多 Java 程序员对 TCP 的理解只有一个三次握手,四次挥手的认识,我觉得这样的原因主要在于 TCP 协议本身稍微有点抽象(相比较于应用层的 HTTP 协议);其次,非框架开发者不太需要接触到 TCP 的一些细节。其实我个人对 TCP 的很多细节也并没有完全理解,这篇文章主要针对微信交流群里有人提出的长连接,心跳的问题,做一个统一的整理。
kirito-moe
2019/03/15
3.2K0
相关推荐
TCP keepalive特性解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档