我是靠谱客的博主 机灵保温杯,最近开发中收集的这篇文章主要介绍andorid 判断网络是否断开_Wireshark网络分析(五)TCP keepalive保活机制分析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

最近处理某个交易所相关程序时,按照接入要求需要在应用层面发送心跳消息,本文基于wireshark对于TCP keepavalie保活机制进行了分析。

TCP Keepalive保活机制作用

检查TCP连接对端状态

假设A和B之间完成了TCP三次握手协议,A等待B发送数据,此时B宕机了,B没有发送任何数据到A。而A此时不知道B宕机了。B重启之后,A认为连接是正常的。此时如果A发送数据到B,B返回RST数据包,A收到后关闭连接。

而通过保活机制,则可以发现上述连接中断的情况。

43076d4377f3e63392e0a2322ff3b845.png

防止因网络不活跃被断开

代理或者防火墙可能会判断所有的连接是否活跃,如果在一段时间内不活跃,则断开该连接。为防止被断开,定期的发送数据是不错的一种方法。

3c8cbf51ea84b9c5382f01c1e7ef4652.png

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异常,及时发现连接中断的情况。

cf00efb16ee263cb46353942a88a01f3.png

从服务端B主机查看:

  • 分组6收到了保活数据包,分组7回复ack。

f0b799de7d695bfad6dbfbf0944bfee5.png

小结

通常应用程序自定义定义心跳机制,自己实现一个ping-pong逻辑和协议,并支持设置空闲时长,重试次数,重试间隔等。而主流操作系统中TCP协议本身也实现了保活机制,但默认关闭,需要应用程序创建socket时打开。同时修改内核参数,也就是统一设置空闲发送时间间隔,个人觉得并不灵活。但是如果应用程序设计ping-pong,多了一定的工作,多代码就多bug嘛。4ab38f179b6559cbfc898febbf4759b3.png

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保活机制分析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部