TCP定时器

一、TCP的7种定时器

1、建立连接定时器(connection-establishment timer)

2、重传定时器(retransmission timer)

3、延迟应答定时器(delayed ACK timer)

4、坚持定时器(persist timer)

5、保活定时器(keepalive timer)

6、FIN_WAIT_2定时器(FIN_WAIT_2 timer)

7、TIME_WAIT定时器(TIME_WAIT timer,也叫2MSL timer)

二、这些定时器的特点及应用场景

1、建立连接定时器(connection-establishment timer)

顾名思义,这个定时器是建立连接时候使用的,TCP建立连接需要3次握手,如下图所示:

TCP定时器

建立连接的过程中,在发送SYN时,会启动一个定时器(默认应该是3秒),如果SYN丢失了,那么3秒后会重新发送SYN包,当然也不会一直没完没了的发SYN包,

在/proc/sys/net/ipv4/tcp_syn_retries可以设置到底要重新发送几次SYN包。

2、重传定时器(retransmission timer)

重传定时器在TCP发送数据段时设定,在计时器超时后没有收到返回的确认ACK,发送端就会重新发送队列中需要重新传的报文段。使用RTO重传计时器一般有如下规则:

a、当TCP发送了位于队列最前端的报文段后就启动这个RTO计时器;

b、如果队列为空则停止计时器,否则重启计时器;

c、当计时器超时后,TCP会重传发送队列最前端的报文段;

d、当一个或者多个报文段被累计确认后,这个或者这些报文段就会被清除出队列。

重传计时器保证了接收端能够接受到对是的报文段,继而抱枕了接收端交付给接受进程的数据始终是有序完整的。因为接收端永远不会把一个失序不完整的报文段交付给接收进程。

3、延迟应答定时器(delayed ACK timer)

延时应答也被称为捎带ACK,这个定时器是在延迟应答的时候使用的。为什么要延时应答,延时应答是为了提高网络传输的效率。

假设服务器端接收到客户端的数据后,不是立刻回ACK给客户端,而是等一段时间,这样如果服务器端要是有数据发给客户端,那么这个ACK就和服务器端的数据一起发给

客户端了,这样就立即回给客户端一个ACK节省了一个数据包。

4、坚持定时器(persist timer)

我们知道的TCP通过让接收方指明希望从发送方接受的数据字节数(窗口大小)来进行流量控制。如果窗口大小为0会发生什么情况呢?这将有效地阻止发送方传输数据,直到窗口变为非零为止。接收窗口变为非零,就会发送一个确认的ACK指明需要的报文段***以及窗口大小。

如果这个确认报文ACK丢失了,则双方就有可能因为等待对方二使连接终止:接收方等待的数据,而发送方在等待允许它继续发送数据的窗口更新。为了防止这种死锁情况的发生,发送方使用一个坚持定时器来周期性的向接收方查询,以便发现窗口是否已增大。这些从发送方发出的报文段称为窗口探查。

5、保活定时器(keepalive timer)

TCP连接建立的时候指定了SO_KEEPALIVE,保活定时器才会生效,如果客户端和服务器长时间没有数据交互,那么需要保活定时器来判断是否对段还活着,但是这个其实

很不实用,因为默认是2小时没有数据交互才探测,时间实在太长了。如果你真的要确认对端是否活着,那么应该自己实现心跳包,而不是依赖于这个保活定时器。

6、FIN_WAIT_2定时器(FIN_WAIT_2 timer)

主动关闭的一段调用完close以后则进入FIN_WAIT_2状态。如果这个时候因为网络突然断掉,被动关闭的一段宕机等原因,导致主动关闭的一段不能收到被动关闭的一段

发来的FIN,主动关闭的一段也不能一直等着,站着资源不撒手,这个时候就需要FIN_WAIT_2定时器出马了,如果在该定时器超时的时候,还没有收到被动关闭一段发来的FIN,

那么就直接释放这个这个链接。FIN_WAIT_2定时器的时间可以从/proc/sys/net/tcp_fin_timeout中查看和设置。

7、TIME_WAIT定时器(TIME_WAIT timer,也叫2MSL timer)

TIME_WAIT是主动关闭的一段最后进入的状态,而不是直接变成CLOSED的状态,为什么呢?第一,万一被动关闭的一段在超时时间内没有收到最后一个ACK,则会重发最

后的FIN,2MSL(报文段最大生存时间)等待时间保证了重发的FIN会被主动关闭的一段收到且重新发送最后一个ACK;另外一个原因是在2MSL等待时间时,任何迟到的报文

段会被接受并丢弃,防止来的TCP连接的包在新的TCP连接里面出现。不可避免的,在这个2MSL等待时间内,不会建立同样(源IP,源端口,目的IP,目的端口)的连接。