常见的TCP定时器

时间:2022-08-03 23:29:49

TCP 是提供可靠的传输层,它使用的方法之一就是确认从另一端收到的数据。但是数据和确认都可能会丢失,TCP 通过在发送时设置一个定时器来解决这个问题。如果当定时器溢出时还没收到确认,它就会重传该数据。

常见的四种TCP定时器(Timer):


重传计时器:Retransmission Timer

坚持计时器:Persistent Timer

保活计时器:Keeplive Timer

时间等待计时器:Time_Wait Timer


时间等待计时器在TCP的四次挥手期间,客户端在响应了服务器的关闭连接响应报文后,当TCP关闭连接时,并不认为这个连接就真正关闭了,会进入time-wait状态,在时间等待期间,连接还处于一种中间过渡状态。这样就可以使重复的fin报文段在到达终点后被丢弃,这个计时器的值通常设置为一格报文段寿命期望值的两倍。

 

重传定时器 :TCP发送的报文,可能会在传输途中被丢失,但发送方不知道该报文已丢失,接收方并不知道发送方已经发过该报文,一直在等待发送方发送该报文。此时就需要一个重传定时器。 

当发送方没有在规定时间内收到接收方发来的对报文的确认,就会重新发送该报文,并重新设置定时器;如果发送方在规定时间内收到了接收方的确认,就撤销重传定时器。 
重传时间的设置,采用了自适应算法,它记录了一个报文段发出的时间,以及收到相应确认的时间。这两个时间差就是RTT。 
新的RTTs=(1-α)×(旧的RTTs)+α×(新的RTT样本) 
其中,RTTs是RTT的加权平均值。0≤α<1,表示新的RTTs值和旧的RTTs值相比变化不大,若α接近1,则表示影响较大。 
显然,超时重传时间RTO应略大于RTTs. 
RTO = RTTs+4×RTTd 
其中,RTTd是RTT的偏差的加权平均值。当地一次测量时,RTTd值取为RTT的一半。之后的测量用下面的计算公式: 
新的RTTd = (1-β)×(旧的RTTd)+β×|RTTs - 新的RTT样本| 
其中,β推荐为0.25。 


坚持计时器 :坚持计时器主要解决零窗口通知导致死锁的问题。 
刚开始接收端向发送端发送了一个零窗口的报文。之后,接收端的窗口有一定空间可以接收数据,所以就向发送端发送了一个有空余窗口报文段,但是该报文段在传输过程中被丢失。发送端就一直以为接收端没有空余窗口,而接收端知道自己已经发送了有空余窗口报文段给发送方,但不知道该报文段已经丢失。所以双方都在等待,可能会造成死锁。 
解决方法:TCP为每一个连接都设置了坚持计时器。当发送端收到零窗口的确认时,就启动计时器,当计时器截止到期时,发送端就发送一个特殊的报文段叫,探测报文段。探测报文段只有一个字节的数据,它的序号不需要确认,甚至在确认其他报文段时也不需要计算在内。探测报文段提醒接收端,确认已丢失,必须重传。 
此时坚持计时器的值会重新设置,如果在截止期内仍没有收到来自接收端的响应,就会重新发送一个探测报文段,并将坚持计时器的值加倍并复位。发送端继续发送探测报文段,并将坚持计时器的值加倍并复位。直到该值增大到阀值(通常为60s)为止。之后每隔60s发送端就发送一个报文,直到接收方发送有空余窗口报文。


保活计时器 :假设 客户端已经主动与服务器建立了TCP连接,但客户端突然出故障了。那么服务器就不能再接收客户端发来的数据了。但服务器并不知道客户端出了故障,服务器仍旧在等待,且一定不会收到来自客户端的数据,那么服务器就白等了。 

为了让服务器不会一直等待,可以设置保活计时器。服务器每收到来自客户端的数据,就重新设置保活计时器,时间设置通常为2小时。若2小时没有收到客户端的数据,服务器就发送一个探测报文段,以后每隔75分钟发送一次。若一连发送10个探测报文段后客户端仍然没有响应,服务器就认为客户端出了故障,接着就关闭这个连接。