TCP_KEEPALIVE功能可以用来检测或保持基于TCP协议的客户端和服务器之间的链路畅通。
当客户端和服务器之间长时间没有数据通信时,协议栈会发送一个特殊的空数据包,用来检测链路是否正常。
接收到这个空数据包的一方会自动发送一个应答包,表示网络链路通信正常。
发送方如果在规定的时间内没有收到应答包,则表示链路中断,自动断开TCP连接,并通知应用层TCP连接断开。
整个交互逻辑完全在协议栈内完成,不需要在应用层做额外的工作,比较方便。
应用示例:
如下图所示,两个交换机中间的网线损坏,导致网络通信失败,客户端与服务器端均不知道网线已经断开。
只能通过应用层心跳包或者开启TCP_KEEPALIVE来实现断线检测。
LWIP目前的版本也支持TCP_KEEPALIVE功能,但默认是关闭状态。
要使用LWIP的TCP_KEEPALIVE功能,需要如下配置:
1.修改lwipopts.h添加以下内容:
//KEEPALIVE
#define LWIP_TCP_KEEPALIVE 1
#define TCP_KEEPIDLE_DEFAULT 3000 //3秒内双方无数据则发起保活探测
#define TCP_KEEPINTVL_DEFAULT 1000 //1秒发送一次保活探测
#define TCP_KEEPCNT_DEFAULT 3 //3次探测无响应则断开
2.创建TCP连接时,需要添加以下代码:
......
struct tcp_pcb *pcb;
pcb = tcp_new();
pcb->so_options |= SOF_KEEPALIVE; //开启TCP_KEEPALIVE标记
err = tcp_connect(ctx->pcb, &ip, port, lwip_tcp_connect_callback);
......
3.按照以上1,2方法开启KEEPALIVE功能之后,如果长时间没有发送或接收到数据,则会发起KEEPALIVE检测。
如果发送3次探测都没有收到应答,LWIP则会断开这条TCP连接,应用层会收到remote closed的回调事件。