[TCP/IP详解]:TCP保活机制

1. 简介

TCP协议当中,没有其它网络协议中的轮询机制,如果TCP连接双方都不向对方发送数据,那么TCP连接的两端就不会有任何数据交换

这意味客户端进程可以与服务器建立连接之后,离开几天,几个星期,连接依旧存在

然而实际上在大多数应用层协议当中会建立超时计时器,中间的路由器也不会持久保存连接状态,所以上面的情况一般不会发生

TCP保活机制用于解决上面的问题,关于保活机制有一些注意点:

  • 保活机制不是TCP规范中的一部分,然而大多数实现当中都提供了保活机制
  • 保活机制是一个可选的功能,他可能会导致一个正常的连接由于中间路由器的短暂断开而导致连接终止
  • 保活功能一般是为服务器提供的,服务器希望直到客户端进程是否已经结束,以避免为他们绑定不必要的资源
  • 那些实现长时间交互服务的服务器可能不希望使用保活功能,如ssh

2. 细节

保活功能在默认情况下是关闭的,连接双方可以选择性的打开

  • 机制

    • 建立TCP连接后,如果在保活时间(keepalive time)内连接处于非活动状态,那么启用了保活功能的一方就可以向接收方发送一个保活探测报文
    • 如果发送方没有收到对应的响应报文,那么在**保活时间间隔(keepalive interval)**之后,发送方会再次发送保活探测报文
    • 如果保活探测报文的发送次数到达了**保活探测数(keepalive probe)**, 这是对方主机将被确认为不可到达,连接终止
  • 保活探测报文

    保活探测报文是一个空或者只包含一个字节的报文段,其Seq字段为接收到的最大ACK - 1, 即是一个垃圾数据

  • 接收方状态

    接受方可能处于以下4中状态之一:

    • 仍在工作,报文可以正常到达

      此时接收方将返回一个保活响应报文,发送方将保活计时器重置

      每当连接有数据传输时,保活计时器的值都会被重置

    • 已经崩溃,报文无法到达

      此时发送方会持续发送保活探测报文,当发送保活探测数数量的报文时,就会停止发送,断开连接

    • 崩溃后重启

      此时接收方会丢弃关于之前的TCP连接的所以记录,所以无法识别发送方发过来的报文,接收方发送RST报文段作为响应

    • 仍在工作,但是响应报文无法到达请求段

      由于网络延迟,可能会发生这种情况,但是发送端无法识别该情况与状态2的区别,因此和状态2一样的进行处理

  • Linux的相关变量

    • /proc/sys/net/ipv4/tcp_keepaliver_time: 保活时间, 默认是7200秒
    • /proc/sys/net/ipv4/tcp_keepalive_interval: 保活时间间隔,默认是75秒
    • /proc/sys/net/ipv4/tcp_keepalive_proves: 保护探测数,默认是9次