超时定时器


超时定时器也称为超时重传定时器,这个定时器是我们接触的第一个定时器,在《可靠传输的基本原理》章节已有讲解,这里简单回顾一下。
超时定时器主要应用在TCP的可靠传输协议里面,是为了控制可能发生丢失的报文而设计的定时器,当TCP协议发送端发送一个报文时,就会为该报文设置一个超时定时器。
如果在超时定时器结束之前收到了来自接收端对该报文段的确认,则撤销这个定时器。
如果在超时定时器结束时仍然没有收到来自接收端对该报文段的确认(超时),则认为这个报文可能已经丢弃,发送端重新发送该报文,并重新设置一个超时定时器。
需要注意的是,发送端在超时定时器撤销之前,必须继续缓存已发送未确认的报文,直到发送端收到了来自接收端的确认。


坚持定时器


坚持定时器是使用滑动窗口进行流量控制的时候而设置的,这个定时器是我们接触的第二个定时器,在《TCP的流量控制》章节已有讲解,这里简单回顾一下。
要理解坚持定时器,需要理解“零窗口通知”的情况。我们知道接收端通过调整接收窗口的大小可以控制发送端的发送速度,当接收端把接收窗口调小时,那么发送端就会调小发送的流量。
这就可能产生一种情况,就是接收端的缓存区已经满了,这个时候接收端会给发送端发送一个“零窗口”的消息,表示说“当前我已经没有余力处理更多的数据了”,这就是“零窗口通知”的情况。
当出现这种情况的时候,双方都会陷入等待的状态,发送端等待接收端的窗口调大,接收端等待发送端发送的数据。当接收端窗口可以调大的时候,接收端会发送窗口调大的信息给发送端,但是这个消息是不可靠的,也即是这个消息可能会在传输中丢失,并且不会被感知到丢失和重传。
如果这个消息在发送过程中丢失的话,那么发送端和接收端就会进入死锁状态,因为接收端认为“我已经把窗口调大的消息发送出去了,发送端理应发送新的消息给我才对”,所以接收端会一直等待发送端的消息;而发送端因为没有收到窗口调大的消息,则认为“接收端还没有调大窗口,因此我不能发送”,发送端也会一直等待。
因此为了解决这个问题,当发送端收到窗口为零的消息之后,会启动一个坚持定时器来周期性主动的向接收方查询,以便发现窗口是否增大,这个就是坚持定时器的作用。

时间等待计时器

时间等待定时器是我们学习的第三个定时器,这个定时器我们在《TCP连接的四次挥手》章节已有讲解,这里简单回顾一下。
时间等待计时器(Time-Wait)是由主动关闭TCP连接的一方设置的,当主动关闭TCP连接的一方收到来自对方的FIN报文的时候(第三次挥手),则认为对方也可以关闭TCP连接,这个时候主动关闭TCP连接的一方发送一个消息确认的报文(第四次挥手),并启动这个时间等待计时器,这个计时器会等待2倍MSL的时间,MSL(Max Segment Lifetime),最大报文段寿命。
以下为方便讨论,我们把主动关闭的一方称为A,被动关闭的一方称为B。
这个定时器主要是为了正确关闭一个TCP连接而考虑的,这主要是为了保证A在对最后一个FIN报文(第三次挥手)发送确认的报文可以到达B。
当A发出这个报文之后,就会启动2MSL计时器,注意,这个报文是有可能在网络传输过程中丢失的,如果B收不到这个确认,那么B会重新发送一次FIN报文,A会重新收到这个报文并重传一次最后的确认,并重新启动2MSL计时器,直到双方正常结束TCP连接。2MSL时间可以保证当B没有收到确认时,B可以再次发出FIN报文,并且A可以再次收到并重新发送确认,所以2MSL的时间可以保证连接正常结束。


保活计时器


保活计时器是TCP协议里面的第四个计时器,这个计时器也是课程内容中没有介绍的,因此需要注意这个定时器。
保活计时器,顾名思义,保活是这个计时器的主要目的,他是为了保活TCP连接而设计的,保活定时器可以防止TCP连接的两端出现长时期的空闲,当一方出现状态变化或故障时,另一方没有察觉的情况。
设想连接双方在建立连接后,只传输了一些数据,然后就都保持静默了,双方也都没有关闭连接(这种情况经常存在),如果这个时候其中一方已经故障,那么这个连接将会永远被打开,如果被连接的一方是服务端的话,那将浪费很多服务端的资源。
因此为了解决这个问题,服务端一般都会设置一个保活定时器,每次收到对方的数据则重置这个定时器,如果定时器超时,服务端则发送探测报文段,探测客户端是否还在线,如果没有收到响应的话,那么则认为客户端已经断开连接了,因此服务端也会终止这个连接。
保活定时器其实有很广泛的应用,在今天,很多的分布式系统,都会使用保活定时器来检测其他节点是否在线还是已经故障,或者其他节点也会每隔一段时间向主节点上报心跳信息以证明在线,这些都是保活定时器在更多领域的广泛应用。

TCP的四个定时器对深入理解TCP协议的细节非常有帮助,这四个定时器也是面试笔试中对应聘者考察的一个知识点,因此希望同学们都能够理解TCP的四个定时器。