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);
}

// 连接到服务器
// ...

// 可选步骤:获取套接字选项的当前值进行验证
// ...

posted @ 2023-07-17 21:01  武平宁  阅读(134)  评论(0)    收藏  举报