TCP 的 keeplive保活机制

本文介绍TCP保活机制的原理及配置方法,通过客户端定期发送保活数据防止服务器因长时间无数据传输而关闭连接。适用于WebSocket等需长期保持连接的应用场景。

在一般情况下,TCP在网路为了避免半连接状态(比如客户端已经掉线服务器还在提供资源),会在长时间没有数据传输时主动关闭连接,但很多应用场景下,如websocket,连接需要一直保持,以便于客户端随时能接收到服务器的消息。只要客户端每隔一段时间向服务器发送一条保活数据,这样服务器就不会主动关闭连接。

为了不影响业务数据,一方会发送与前一个seq相同的数据包,而另一方则会回复同样的ack,如果另一方没有回复,就说明连接有问题。这就是保活的原理。

TCP默认没有数据情况下2小时后发送一次保活消息,在/proc/sys/net/ipv4目录下的 tcp_keepalive_time 文件中可以设置。tcp_keepalive_intvl 文件表示保活消息的间隔,默认是75s,tcp_keepalive_probes 文件表示累计没有收到的回复数算掉线。也可以针对某个socket来设置:

int keeplive = 1; // 打开keepkive属性
int keepidle = 60; // 60s没有数据keeplive激活
int keepinterval = 5; // keeplive间隔5s
int keepcount = 3; // 探测失败尝试次数
setsocket(fd,SOL_SOCKET,SO_KEEPALIVE,(void*)&keeplive,sizeof(keeplive);
setsocket(fd,SOL_SOCKET,SO_KEEPPIDLE,(void*)&keeppidle,sizeof(keeppidle);
setsocket(fd,SOL_SOCKET,SO_KEEPINTVL,(void*)&keepintvl,sizeof(keepintvl);
setsocket(fd,SOL_SOCKET,SO_KEEPCNT,(void*)&keepcount,sizeof(keepcount);

在保活情况中,有三种情况

TCP 自带的机制(**TCP Keepalive**)是一种由操作系统层面实现的机制,用于检测一个已经建立的 TCP 连接是否仍然有效。它**不是 TCP 协议规范中的强制功能**,但大多数操作系统(如 Linux、Windows、macOS)都支持配置。 --- ### 🔍 TCP Keepalive 的工作原理: 当 TCP 连接在一段时间内没有数据传输时,如果启用了 Keepalive,操作系统会自动发送探测包(Keepalive probes)来确认对方是否仍然在线。 具体流程如下: 1. **空闲超时(keepalive time)**: - 如果在一个 TCP 连接上一段时间内(默认 Linux 是 7200 秒 = 2 小时)没有数据传输,操作系统会开始发送 Keepalive 探测包。 2. **发送探测包(keepalive probes)**: - 操作系统发送一个不携带数据的特殊 TCP 包(ACK 标志位为 1)。 - 如果对方正常响应(回复 ACK),说明连接仍然有效。 3. **失败重试(keepalive retries)**: - 如果没有响应,操作系统会尝试发送多个探测包(默认 Linux 是 9 次)。 - 每次探测之间有间隔(keepalive interval,默认 Linux 是 75 秒)。 4. **断开连接**: - 如果所有探测都失败,操作系统会认为连接失效,并关闭该连接。 --- ### 🛠️ 如何启用 TCP Keepalive? #### 在 Python 中启用: ```python import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 启用 keepalive sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) # 在 Linux 上还可以设置 TCP 层参数(需要使用 TCP_XXX 常量) # sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPIDLE, 60) # 空闲多久后开始探测(秒) # sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPINTVL, 10) # 探测包发送间隔(秒) # sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_KEEPCNT, 5) # 探测失败重试次数 ``` > ⚠️ 注意:`TCP_KEEPIDLE`, `TCP_KEEPINTVL`, `TCP_KEEPCNT` 这些选项在 Windows 上不支持,Linux 上才有效。 --- ### 🆚 TCP Keepalive vs 应用层心跳: | 特性 | TCP Keepalive | 应用层心跳 | |------|----------------|----------------| | 实现层级 | 操作系统内核 | 应用程序 | | 配置方式 | 系统调用设置 | 自定义协议 | | 灵性 | 低(参数受限) | 高(可自定义频率、内容) | | 探测速度 | 慢(默认 2 小时才开始探测) | 快(可设为几秒) | | 适用场景 | 长连接、服务器资源清理 | 实时性要求高的系统 | --- ### ✅ 使用建议: - 如果你希望**快速检测连接状态**,建议使用**应用层心跳机制**。 - 如果你只是希望**清理长时间空闲的连接**,可以启用 TCP Keepalive--- ### 📌 总结: TCP 自带的机制Keepalive)是一种操作系统层面的连接检测机制,适合用于清理长时间空闲的连接。但它探测周期长、不够灵,若需要更精确的连接状态检测,应结合**应用层心跳机制**。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值