Skip to content

Latest commit

 

History

History
52 lines (40 loc) · 3.07 KB

17.2_keepalive机制.md

File metadata and controls

52 lines (40 loc) · 3.07 KB

17.2 keepalive机制

先来一个问题,TCP连接一旦建立后,是不是这个连接可以一直保持? 答案是否定的,操作系统在实现TCP协议的时候都做了一个限制,这个限制可以参考配置:

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

我们看到默认这个tcp_keepalive_time的值为7200s,也就是2个小时,这个值代表如果TCP连接发送完最后一个ACK包后,如果超过2个小时,没有数据往来,那么这个连接会断掉。那么我们如何才能保持住这个连接呢?实际上,这就是TCP的keepalive机制,哦,说法不严谨,TCP协议并没有规定如此,但是很多的操作系统内核实现TCP协议时,都加上了这个keepalive机制,那么这个功能默认是关闭的,那这个keepalive机制到底是如何的呢?也就是,如果TCP之间没有任何数据来往了在tcp_keepalive_time(7200s,2h)后,服务器给客户端发送一个探测包,如果对方有回应,说明这个连接还存活,否则继续每隔tcp_keepalive_intvl(默认为75s)给对方发送探测包,如果连续tcp_keepalive_probes(默认为9)次后,依然没有收到对端的回复,那么则认为这个连接已经关闭。

tcp keepalive默认不是开启的,如果想使用KeepAlive,需要在你的应用中设置SO_KEEPALIVE才可以生效。当然事先我们可以修改这些默认值,方法如下:

在Linux中我们可以通过修改 /etc/sysctl.conf 的全局配置:

net.ipv4.tcp_keepalive_time=7200
net.ipv4.tcp_keepalive_intvl=75
net.ipv4.tcp_keepalive_probes=9

添加上面的配置后输入 sysctl -p 使其生效,你可以使用 sysctl -a | grep keepalive 命令来查看当前的默认配置

tcp keepalive可以通过设置TCP选项设置,设置方法如下:

#include <sys/socket.h>

int setsockopt(int socket, int level, int option_name, const void *option_value, socklen_t option_len);
	 

我们在需要使能Keepalive的socket上面调用setsockopt函数便可以打开该socket上面的keepalive。

第一个参数是要设置的套接字 第二个参数是SOL_SOCKET 第三个参数必须是SO_KEEPALIVE 第四个参数必须是一个布尔整型值,0表示关闭,1表示打开 最后一个参数是第四个参数值的大小。

示例:

 int keepalive = 1;
 setsockopt(incomingsock,SOL_SOCKET,SO_KEEPALIVE,(void*)(&keepalive),(socklen_t)sizeof(keepalive));
                         
 int keepalive_time = 30;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPIDLE,(void*)(&keepalive_time),(socklen_t)sizeof(keepalive_time));
 int keepalive_intvl = 3;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPINTVL,(void*)(&keepalive_intvl),(socklen_t)sizeof(keepalive_intvl));
int keepalive_probes= 3;
 setsockopt(incomingsock, IPPROTO_TCP, TCP_KEEPCNT,(void*)(&keepalive_probes),(socklen_t)sizeof(keepalive_probes));
设置SO_KEEPALIVE选项来开启KEEPALIVE,然后通过TCP_KEEPIDLE、TCP_KEEPINTVL和TCP_KEEPCNT设置keepalive的保活时间、间隔、次数等参数。