TCP/IP协议学习之七(TCP的保活定时器keepalive选项)

时间:2023-01-08 00:24:53

考虑下这种场景,一个TCP连接已经建立,但是双方没有数据交互,这样的话,不管这两个host之间的路由器奔溃,或者网线断掉,只要两个host没有被重启,这个连接依然保持。这样的话浪费不必要的带宽,成本会增加。其实TCP协议中有一个keepalive定时器。

如果一个连接长时间没有任何动作,那么服务器就会发送一个探查报文段给客户端。然后客户端有以下四种反馈:

1、客户端返回正常的ACK,则服务器知道客户主机是存活的,keepalive定时器两个小时后复位。如果在这两小时计时到期之前,这个连接上有数据交互,则复位保活定时器,为接下来的2小时准备;

2、客户主机已经崩溃,并且关闭或者正在重新启动。服务器不能收到探查响应,默认75秒后超时。服务器总共发送10个探查包,每隔75秒一次,如果一个响应都没有收到,则终止连接;

3、客户主机崩溃并且已经重新启动。服务器收到探查响应,此响应只是一个复位,服务器收到后终止这个连接;

4、客户主机正常运行,但是服务器不可到达,这种情况与2类似。

Linux下keepalive选项默认是关闭的,在编写Socket程序的时候打开keepalive选项如下操作:

int keepAlive = 1;  // 开启keepalive属性. 缺省值: 0(关闭)
int keepIdle = 60; // 如果在60秒内没有任何数据交互,则进行探测. 缺省值:7200 s
int keepInterval = 5;// 探测时发探测包的时间间隔为5秒. 缺省值:75 s
int keepCount = 2; // 探测重试的次数. 全部超时则认定连接失效..缺省值:10次
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));
在Linux系统配置中的位置如下:

 /proc/sys/net/ipv4/tcp_keepalive_time 
/proc/sys/net/ipv4/tcp_keepalive_intvl
/proc/sys/net/ipv4/tcp_keepalive_probes