欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TCP连接探测中的Keepalive和心跳包

程序员文章站 2024-03-22 22:05:04
...

1、TCP保活的必要性

1)我们知道TCP是无感知的虚拟链接,中间断开两端并不会感知到。(注:关于虚拟连接就是说我并不实际感知你的存在,只是因为我存储了你对应的一个结构和状态就认为你实际存在)

2)很多防火墙等会对空闲的socket自动关闭;连接的双方在链接空闲状态时,任意一方意外崩溃、宕机、网线断开、路由器故障等事情都是有可能发生的。

3)对于非正常的断开服务器自身并不能检测到,除非继续在此连接上发送数据导致错误返回,我们才能判断连接出现故障。显然这不是我们真正需要的。

4)我们希望服务端和客户端都能及时有效地检测到连接失败,然后自动的进行一个清理工作并把错误报告给用户。

2、保活的两种方式

1)应用层面的心跳机制

很好理解应用层实现探测。例如自定义心跳消息头客户端主动发送,服务端可回也可不回。这里不细讲。

2)TCP协议自带的保活功能

TCP默认不开启Keepalive功能,因为开启后需要消耗额外的带宽和流量,尽管微不足道。另外Keepalive设置不合理时可能会因为短暂的网络波动而错误的断开健康的TCP链接。

3、类Unix平台设置keep-alive:

前面说了keepalive默认是关闭的,毕竟会产生流量方面的开销,虽然说很小。一次需要用户手动开启,有两种方式

1)代码层面针对单个socket进行单独的设置(没错用到的就是setsockopt)。代码如下,都是这么写的。

int keepAlive = 1;   // 开启keepalive属性. 缺省值: 0(关闭)  
int keepIdle = 60;   // 如果在60秒内没有任何数据交互,则进行探测. 缺省值:7200(s)  
int keepInterval = 5;   // 探测时发探测包的时间间隔为5秒. 缺省值:75(s)  
int keepCount = 2;   // 探测重试的次数. 全部超时则认定连接失效..缺省值:9(次)  
setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void*)&keepAlive, sizeof(keepAlive));  
setsockopt(s, SOL_TCP, TCP_KEEPIDLE, (void*)&keepIdle, sizeof(keepIdle));  
setsockopt(s, SOL_TCP, TCP_KEEPINTVL, (void*)&keepInterval, sizeof(keepInterval));  
setsockopt(s, SOL_TCP, TCP_KEEPCNT, (void*)&keepCount, sizeof(keepCount));  

注:使用时需要#include <netinet/tcp.h>, 否则SOL_TCP和TCP_KEEPIDLE等3个宏找不到. 

2)修改配置文件,对整个系统所有的socket生效。

cat命令查看到系统中这几个默认的值.

cat /proc/sys/net/ipv4/tcp_keepalive_time  
7200  
cat /proc/sys/net/ipv4/tcp_keepalive_intvl  
75  
cat /proc/sys/net/ipv4/tcp_keepalive_probes  
9

修改它们:
echo 60 > /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

 

相关标签: socket socket