tcp定时器

来源:互联网 发布:玄武指弹吉他教室知乎 编辑:程序博客网 时间:2024/06/05 02:06

TCP是一个面向连接的,可靠的,流式传输的协议。
为了维护安全和可靠,在TCP的里面有7种定时器:

  • 建立连接定时器(connection-establishment timer)
  • 重传定时器(retransmission timer)
  • 延迟应答定时器(delayed ACK timer)
  • 坚持定时器(persist timer)
  • 保活定时器(keepalive timer)
  • FIN_WAIT_2定时器(FIN_WAIT_2 timer)
  • TIME_WAIT定时器 (TIME_WAIT timer, 也叫 2MSL timer)

建立连接定时器

顾名思义,这个定时器是在建立连接的时候使用的, 我们知道, TCP建立连接需要3次握手,如果client在连接server的时候,在发送SYN的时候,会启动一个定时器(默认应该是3秒),如果SYN包丢失了,那么3秒以后会重新发送SYN包的(当然还会启动一个新的定时器,设置成6秒超时),当然也不会一直没完没了的发SYN包。


重传定时器

对于TCP发送出去的数据包, 需要等待对端发来ACK才能从内存里面删除, 那么如果对端没有发送ACK怎么办? 重传呗, 在发送数据的同时,在设置一个超时时间(一般设置成2个RTT的时间),如果在这个超时时间内, 没有收到ACK,那么就重传刚才发送的数据。


延迟应答定时器

顾名思义,这个定时器是在延迟应答的时候使用的。
为什么要延迟应答呢?比如客户端发一段数据给服务端,服务端本应该立刻回ACK给客户端的,延迟应答是为了提高网络传输的效率,比如服务端收到客户端的数据后,不是立刻回ACK给客户端,而是等一段时间(一般最大200ms),这样如果服务端要是有数据需要发给客户端,那么这个ACK就和服务端的数据一起发给客户端了,这样比立即回给客户端一个ACK节省了一个数据包。


坚持定时器

坚持定时器是在收到receive window为0的时候开始启动的.
比如最后一个ACK丢了,那么发送端就永远认为接收端的窗口是0,那么就发不了数据了。这个时候就需要坚持定时器,每隔一段时间(第一个探测包是在收到窗口为0的消息后的5秒)发送一个字节的探测包给服务端,如果服务端窗口不是0了,会在ack里面更新窗口大小的。


保活定时器

如果客户端和服务端长时间没有数据交互,那么需要保活定时器来判断是否对端还活着,但是这个其实很不实用,因为默认是2小时没有数据交互才探测,时间实在是太长了。


FIN_WAIT_2定时器

在主动关闭的一端调用完close以后(发FIN包给对端, 并且收到对端对FIN的ACK)则进入到FIN_WAIT_2状态,那么这个时候如果和对端之间的网络坏了或者对端程序有问题了一直不close,或者对端机器直接断电了,本端不能一直傻等吧,所以就需要这个定时器,如果在这个定时器超时的时候,还是没收到对端的FIN包,那么不好意思不等了,直接释放这个链接。


TIME_WAIT定时器

在连接终止期使用,当TCP关闭连接时,并不认为这个连接就真正关闭了,在时间等待期间,连接还处于一种中间过度状态。这样就可以时重复的FIN报文段在到达终点后被丢弃,这个计时器的值通常设置为一格报文段寿命期望值的两倍。

TIME_WAIT是主动关闭连接的一端最后进入的状态,而不是直接变成CLOSED的状态,为什么呢?
第一个原因是万一最后一个ACK丢失了,对端会重传的,这个在超时之前的重新收到对端的FIN也可以回ACK,而不是RST。
另外一个原因是防止老连接的包在新连接里面出现,影响了新连接。有这个2MSL的时间,可以在2个MSL时间之内不会建立同样四元组(源IP, 源端口,目的IP,目的端口)的连接,也就不会出现老的包影响新连接的事情。

原创粉丝点击