为什么基于TCP的应用需要心跳包(TCP keep-alive原理分析)

为什么基于TCP的应用需要心跳包(TCP keep-alive原理分析)

TCP keep-alive的三个参数

用man命令,可以查看linux的tcp的参数:

1

man 7 tcp

其中keep-alive相关的参数有三个:

123456789101112

tcp_keepalive_intvl (integer; default: 75; since Linux 2.4) The number of seconds between TCP keep-alive probes.tcp_keepalive_probes (integer; default: 9; since Linux 2.2) The maximum number of TCP keep-alive probes to send before giving up and killing the connection if no response is obtained from the other end.tcp_keepalive_time (integer; default: 7200; since Linux 2.2) The number of seconds a connection needs to be idle before TCP begins sending out keep-alive probes. Keep- alives are sent only when the SO_KEEPALIVE socket option is enabled. The default value is 7200 seconds (2 hours). An idle connection is terminated after approximately an additional 11 minutes (9 probes an interval of 75 seconds apart) when keep-alive is enabled.

这些的默认配置值在/proc/sys/net/ipv4 目录下可以找到。

可以直接用cat来查看文件的内容,就可以知道配置的值了。也可以通过sysctl命令来查看和修改:

12345

# 查询cat /proc/sys/net/ipv4/tcp_keepalive_timesysctl net.ipv4.tcp_keepalive_time#修改sysctl net.ipv4.tcp_keepalive_time=3600

上面三个是系统级的配置,在编程时有三个参数对应,可以覆盖掉系统的配置:

123

TCP_KEEPCNT 覆盖 tcp_keepalive_probes,默认9(次)TCP_KEEPIDLE 覆盖 tcp_keepalive_time,默认7200(秒)TCP_KEEPINTVL 覆盖 tcp_keepalive_intvl,默认75(秒)

tcp keep-alive的本质

TCP keep-alive probe

上面了解了tcp keep-alive的一些参数,下面来探究下其本质。

在远程机器192.168.66.123上,用nc启动一个TCP服务器:

1

nc -l 9999

在本地机器上,用python创建一个socket去连接,并且用wireshark抓包分析

12345678

import sockets = socket.socket(socket.AF_INET, socket.SOCK_STREAM)s.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 20)s.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 1)s.connect(('192.168.66.123', 9999))

上面的程序,设置了TCP_KEEPIDLE为20,TCP_KEEPINTVL为1,系统默认的tcp_keepalive_probes是9。

当网络正常,不做干扰时,wireshark抓包的数据是这样的(注意看第二列Time):

可以看到,当3次握手完成之后,每隔20秒之后66.120发送了一个TCP Keep-Alive的数据包,然后66.123回应了一个TCP Keep-Alive ACK包。这个就是TCP keep-alive的实现原理了。

当发送了第一个TCP Keep-Alive包之后,拨掉192.168.66.123的网线,然后数据包是这样子的:

可以看到,当远程服务器192.168.66.123网络失去连接之后,本地机器(192.168.66.120)每隔一秒重发了9次tcp keep-alive probe,最终认为这个TCP连接已经失效,发了一个RST包给192.168.66.123。

三个参数的具体意义

TCP_KEEPIDLE :这个参数是多久没有发送数据时,开始发送Keep-Alive包的时间,也就是链路空闲时间。TCP_KEEPINTVL:这个参数是指发送Keep-Alive probe后,对方多久没有回应,然后重新再发送keep alive probe的时间间隔TCP_KEEPCNT:这个参数指,连续发送多少次keep alive probe,对方没有回应,认为连接已经失效的重试次数

如果不能理解或者有混淆,仔细对照下上面的两张图片就可以明白了。

为什么应用层需要heart beat/心跳包?

默认的tcp keep-alive超时时间太长

默认是7200秒,也就是2个小时。

socks proxy会让tcp keep-alive失效

socks协议只管转发TCP层具体的数据包,而不会转发TCP协议内的实现细节的包(也做不到),参考socks_proxy。

所以,一个应用如果使用了socks代理,那么tcp keep-alive机制就失效了,所以应用要自己有心跳包。

socks proxy只是一个例子,真实的网络很复杂,可能会有各种原因让tcp keep-alive失效。

移动网络需要信令保活

前两年,微信信令事件很火,搜索下“微信 信令”或者“移动网络 信令”可以查到很多相关文章。

这里附上一个链接:微信的大规模使用真的会过多占用信令,影响通讯稳定吗?

总结

TCP keep-alive是通过在空闲时发送TCP Keep-Alive数据包,然后对方回应TCP Keep-Alive ACK来实现的。

为什么需要heart beat/心跳包?因为tcp keep-alive不能满足人们的实时性的要求,就是这么简单。

相关推荐

如何在Steam上下载求生之路并顺利安装的详细步骤与注意事项
王者荣耀实名认证作用,成年后一年可换绑一次
英国beat365官方登录

王者荣耀实名认证作用,成年后一年可换绑一次

📅 07-14 👁️ 2537
沪牌分期申请后,多久出审核结果?
365网新闻

沪牌分期申请后,多久出审核结果?

📅 01-02 👁️ 627
优质小米miui8的截屏方式
中爱365APP

优质小米miui8的截屏方式

📅 08-28 👁️ 3046
员工工作证制作过程(收藏!如何用Word批量生成工作证?)
300兆光纤买什么路由器?性能推荐与选购指南
英国beat365官方登录

300兆光纤买什么路由器?性能推荐与选购指南

📅 08-30 👁️ 1935
附近爱约(直播交友) v19.0.8 安卓版
365网新闻

附近爱约(直播交友) v19.0.8 安卓版

📅 09-19 👁️ 8580
深度解析迪瑞克斯f01和f08有没有区别?剖析哪个好?真实体验诉说
底妆是什么意思?底妆需要哪些化妆品?
英国beat365官方登录

底妆是什么意思?底妆需要哪些化妆品?

📅 10-02 👁️ 1286
2024模拟经营餐厅类游戏有哪些 好玩的经营餐厅类游戏大全
成吉思汗到底杀了多少人?真的有2亿吗
中爱365APP

成吉思汗到底杀了多少人?真的有2亿吗

📅 07-12 👁️ 683
海之蓝酒送礼怎么样,海之蓝酒作为礼物选取是否得当?