TCP的Keep-Alive机制:链接存在但是没有数据传输,内核怎么处理
服务端/客户端会定期发送探测报文来检测客户端的存活状态。
由三个内核参数控制:
-
首次发送探测报文时间:
net.ipv4.tcp_keepalive_time有报文传输时重置 -
探测报文的发送间隔:
net.ipv4.tcp_keepalive_intvl -
探测报文的最大重试次数:
net.ipv4.tcp_keepalive_probes
内核配置
# sysctl -a | grep tcp_keepalive_
net.ipv4.tcp_keepalive_intvl = 75
net.ipv4.tcp_keepalive_probes = 9
net.ipv4.tcp_keepalive_time = 7200
注意,在默认情况下可能是禁用的,需要应用层设置开启。
Nginx 开启tcp探活机制:
so_keepalive=30m::10
将空闲超时 (TCP_KEEPIDLE) 设置为 30 分钟,将探测间隔 (TCP_KEEPINTVL) 保留为系统默认值,并将探测计数 (TCP_KEEPCNT) 设置为 10 个探测。
客户端设置,示例:
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
perror("socket creation failed");
exit(EXIT_FAILURE);
}
int enable = 1;
if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(enable)) < 0) {
perror("setsockopt: SO_KEEPALIVE failed");
exit(EXIT_FAILURE);
}
int idle_time = 60; // 设置空闲时间为60秒
if (setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &idle_time, sizeof(idle_time)) < 0) {
perror("setsockopt: TCP_KEEPIDLE failed");
exit(EXIT_FAILURE);
}
int interval = 10; // 设置探测报文的发送间隔为10秒
if (setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(interval)) < 0) {
perror("setsockopt: TCP_KEEPINTVL failed");
exit(EXIT_FAILURE);
}
int max_retries = 3; // 设置最大重试次数为3次
if (setsockopt(sockfd, IPPROTO_TCP, TCP_KEEPCNT, &max_retries, sizeof(max_retries)) < 0) {
perror("setsockopt: TCP_KEEPCNT failed");
exit(EXIT_FAILURE);
}
// 连接到服务器
// ...
// 可选步骤:获取套接字选项的当前值进行验证
// ...

浙公网安备 33010602011771号