1.前言
TCP不对ACK报文段进行确认,如果一个ACK丢失了,接收方等待接收数据(因为它已经向发送方通告了一个非0的窗口),而发送方等待允许它继续发送数据的窗口更新。
为防止这种死锁,发送方使用坚持定时器(persist timer)来周期性向接收方询查窗口是否已增大。(发出的报文段叫做窗口探查,window probe)
2.坚持定时器
当TCP服务器收到了客户端的0滑动窗口报文的时候,就启动一个定时器来计时,并在定时器溢出的时候向客户端查询窗口是否已经增大,如果得到非零的窗口就重新开始发送数据,如果得到0窗口就再开一个新的定时器准备下一次查询。通过观察可以得知,TCP的坚持定时器使用1,2,4,8,16……64秒这样的普通指数退避序列来作为每一次的溢出时间。
窗口探查报文包含一个字节的数据。
坚持定时器一直持续到窗口打开或者应用程序关闭。
3.糊涂窗口综合征SWS
(这一部分作者讲的不是很明白,以下内容参考自网络)
TCP的窗口协议,会引起一种通常叫做糊涂窗口综合征(Silly Window Syndrome)的问题,具体表现为,当客户端通告一个小的非零窗口时,服务器立刻发送小数据给客户端并充满其缓冲区,一来二去就会让网络中充满小TCP数据报,从而影响网络利用率。
避免措施:
1.对于接收方:
1)Clark解决方法:只要有数据到达就发送确认,但宣布的窗口大小为零,直到或者缓存空间已能放入具有最大长度的报文段,或者缓存空间的一半已经空了。
2)延迟的确认:延迟一段时间后再发送确认。这表示当一个报文段到达时并不立即发送确认。接收端在确认收到的报文段之前一直等待,直到入缓存有足够的空间为止。延迟的确认防止了发送端的TCP滑动其窗口。当发送端的TCP发送完其数据后,它就停下来了。这样就防止了这种症状。
迟延的确认还有另一个优点:它减少了通信量。接收端不需要确认每一个报文段。但它也有一个缺点,就是迟延的确认有可能迫使发送端重传其未被确认的报文段。
2.对于发送方,只有满足以下条件之一才发送数据:
(1)可以发送一个满长度的报文段(MMS).
(2)可以发送至少接收方通告窗口一半的报文段.
(3)如果以前的数据都被确认或者该连接不使用Nagle算法时,可以发送任意数据.
Nagle算法
发送端的TCP将它从发送应用程序收到的第一块数据发送出去,哪怕只有一个字节。
在发送第一个报文段(即报文段1)以后,发送端的TCP就在输出缓存中积累数据,并等待:或者接收端的TCP发送出一个确认,或者数据已积累到可以装成一个最大的报文段。在这个时候,发送端的TCP就可以发送这个报文段。
对剩下的传输,重复步骤2。这就是:如果收到了对报文段x的确认,或者数据已积累到可以装成一个最大的报文段,那么就发送下一个报文段(x + 1)。
Nagle算法的优点就是简单,并且它考虑到应用程序产生数据的速率,以及网络运输数据的速率。若应用程序比网络更快,则报文段就更大(最大报文段)。若应用程序比网络慢,则报文段就较小(小于最大报文段)。