TCP定时器

  • Post author:
  • Post category:其他



目录


坚持计时器:Persistent Timer


关于窗口大小


保活计时器:Keeplive Timer


TCP有四种定时器:重传定时器,坚持计时器,保活定时器,时间等待计时器。我们主要看其中两种:坚持定时器,保活定时器。

定时器是做什么的呢?

这要提到面试的时候老生常谈的问题:TCP和UDP的区别。最直接的,TCP安全,UDP不安全;那么问题来了,TCP为什么是安全的呢,又是怎么实现的呢?这个答案很长,比如面向连接,全双工,丢包重查等等,也包括我们要讲的定时器。没错,定时器是TCP协议保持数据传输可靠性的一种手段,它就是做这个的。那它怎么做的呢?和定时又有什么关系呢?别急,我们接着看。



坚持计时器:Persistent Timer



TCP是一个面向连接的协议。


发送方发送数据,接收方会对其响应ACK,如果接收方没有按时响应ACK,发送方将重传数据





当接收方开始一个TCP连接时,自身会打开一个接收缓存区作为临时存储,之后再交给程序处理。


当接收方发送一个ACK响应时,接收方会告诉发送者下一次我能接收多少数据,我们管这个叫窗口大小(window size)。一般这个窗口大小就是接收方缓冲区的大小,


用来告知发送方当前本端还能接收的数据长度


。如果接收方不断从网络中接收并缓存数据,但是应用程序并


没有处理缓存的数据


。直到最后,接收方就会向发送方发送一个0窗口的报文段。


关于窗口大小

最早TCP协议涉及用来大范围网络传输时候,其实是没有超过56 kb/s的​连接速度的。因此,TCP包头中只保留了16 bit用来标识窗口大小,允许的最大缓存大小不超过64KB。为了打破这一限制,RFC1323规定了TCP窗口尺寸选择,是在TCP连接开始的时候三步握手的时候协商的(SYN, SYN-ACK, ACK),会协商一个 Window size scaling factor,之后交互数据中的是Window size value,所以最终的窗口大小是二者的乘积。

比如下面这个TCP包头:

Window size value: 1024 or 0000 0100 0000 0000 (16 bits)





0400


Window size scaling factor: 256 or 2 ^ 8

最终的窗口大小即为:1024 × 256 = 262144

书归正传,当发送端A收到来自B的零窗口的确认时,说明B此时已经没有空间接受A发送的数据了,通知A停止发送。A在收到后即停止发送,等待一段时间后,B有了一些空间,可以继续接收了。此时再向A发送非0窗口报文。如果此非0窗口报文在网络中阻塞或者丢失了,那么A将永远以为B没有空间接收数据,B也永远在等待A发来的数据。我以为你不爱,我以为你会来,这就是错过……呸,死锁。

坚持定时器解决的就是这个问题,在A接收到B发送的0窗口报文后,就设立坚持定时器,当定时器到达后,A就像B发送一个探测报文。B收到探测报文后会给出A确认报文。

确认报文中的窗口值不是0,则死锁j解开。

确认报文中的窗口值是0,则重置坚持定时器,并将时间翻倍,但是最大不能超过60秒。(到达60后,以后都是60秒)




//这就是为什么叫定时器


A在发送探测报文后,启动重传定时器,若没有收到B的确认报文,则重传探测报文。

简单地说,避免因为收不到确认报文陷入死锁。



保活计时器:Keeplive Timer


保活定时器比较好理解,顾名思义,就是问“嘿,活着么?”

Client突然溜了,而server并不知道,还在一直等待客户机发来的数据,这样就白白浪费了计算机资源。

在server端设置保活计时器,每收到client的一次消息,就重置保活计时器,时间通常为2小时。若2个小时都没有收到客户机发来的消息,server就像客户机发送一个探测报文(“活着没?”),以后每隔75分钟发送一次。若连续发送了10个探测报文后client仍无响应,则server就会认为client故障(“它死了!”),并断开这次连接。

简单地说,为了防止client故障浪费server资源。



版权声明:本文为m0_56788835原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。