概述
最近处理某个交易所相关程序时,按照接入要求需要在应用层面发送心跳消息,本文基于wireshark对于TCP keepavalie保活机制进行了分析。
TCP Keepalive保活机制作用
检查TCP连接对端状态
假设A和B之间完成了TCP三次握手协议,A等待B发送数据,此时B宕机了,B没有发送任何数据到A。而A此时不知道B宕机了。B重启之后,A认为连接是正常的。此时如果A发送数据到B,B返回RST数据包,A收到后关闭连接。
而通过保活机制,则可以发现上述连接中断的情况。
防止因网络不活跃被断开
代理或者防火墙可能会判断所有的连接是否活跃,如果在一段时间内不活跃,则断开该连接。为防止被断开,定期的发送数据是不错的一种方法。
Linux环境下的TCP 保活机制
Linux TCP协议支持保活机制,默认是关闭的,通过setsockopt打开,并且可以修改内核参数进行配置。
tcp_keepalive_time
发出最后一个数据包到第一次保活探测的间隔时间。
tcp_keepalive_intvl
保活探测的时间间隔。
tcp_keepalive_probes
保活探测没有确认的数目,达到数目之后,通知上层应用该连接异常。
Linux内核中默认值:
cat /proc/sys/net/ipv4/tcp_keepalive_time7200 cat /proc/sys/net/ipv4/tcp_keepalive_intvl75 cat /proc/sys/net/ipv4/tcp_keepalive_probes9
7200秒,即:保活机制等待2个小时之后发出第一个探测,然后间隔75秒再次发送,如果发送了9次都没有收到ack,则标记该连接异常。
TCP 保活机制实验测试
基于上述的分析,笔者建立环境进行实验测试。
基本环境
A主机系统为Ubuntu16,192.168.199.230,B主机系统为Centos8,192.168.199.221。
B主机通过netcat在端口43210监听:
nc -l 43210
配置操作
B主机上面关闭防火墙并启动tcpdump抓取数据包:
systemctrl stop firewalld
A主机修改保活机制内核参数并启动tcpdump抓取数据包:
echo 10 > /proc/sys/net/ipv4/tcp_keepalive_time echo 5 > /proc/sys/net/ipv4/tcp_keepalive_intvl echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes
程序测试
在A主机上运行python连接程序,然后等待接收数据:
import socketdef sock_connect(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(("192.168.199.221", 43210)) s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) while True: try: data = s.recv(1024) print(data) except IOError: print("socket timeout") break s.close()
Tcpdump分析
从客户端A主机查看:
建立连接之后,A、B之间先不发送数据。A主机等待10秒钟,发送了保活数据包(分组4、6),B主机回复了保活确认数据包(分组7);
然后关闭B主机的网卡(也可以通过iptables丢弃数据包);
A主机发送保活数据包但是没有收到确认,因此间隔5秒钟继续发送;
连续发送三个之后,发送了RST+ACK数据包,同时通知应用程序;
应用程序recv出现connect timeout异常,及时发现连接中断的情况。
从服务端B主机查看:
分组6收到了保活数据包,分组7回复ack。
小结
通常应用程序自定义定义心跳机制,自己实现一个ping-pong逻辑和协议,并支持设置空闲时长,重试次数,重试间隔等。而主流操作系统中TCP协议本身也实现了保活机制,但默认关闭,需要应用程序创建socket时打开。同时修改内核参数,也就是统一设置空闲发送时间间隔,个人觉得并不灵活。但是如果应用程序设计ping-pong,多了一定的工作,多代码就多bug嘛。
So,还是自己按照服务端的要求自己写吧。比如:深交所五版交易系统涉及到的交易网关,需要按周期发送心跳消息。tgw会判断N个周期没有收到心跳消息,断开报盘程序的连接。
【文献2】中通过C语言示例对于Tcp keepalive机制做了测试,并分析了内核代码。
参考文献
http://yuweijun.github.io/blog/linux/2016/06/19/howto-tcp-keep-alive.html
https://mp.weixin.qq.com/s/bK0W2zBdUJAAgYzXnrK80w
https://www.wireshark.org/docs/wsug_html_chunked/ChAdvTCPAnalysis.html#:~:text=TCP%20Keep%2DAlive%20ACK&text=The%20current%20sequence%20number%20is%20the%20same%20as%20the%20next,SYN%2C%20FIN%2C%20or%20RST.
最后
以上就是机灵保温杯为你收集整理的andorid 判断网络是否断开_Wireshark网络分析(五)TCP keepalive保活机制分析的全部内容,希望文章能够帮你解决andorid 判断网络是否断开_Wireshark网络分析(五)TCP keepalive保活机制分析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复