TCP-IP详解:糊涂窗口综合症(Silly Window syndrome)

参考教材:TCP/IP详解,卷1:协议    TCP-IP Guide


主要介绍再接收端和发送端速率不匹配的状况下,TCP协议栈滑动窗口动态调整机制产生的一种问题 叫糊涂窗口综合症,有关滑动窗口的知识可以参考文章TCP-IP详解:滑动窗口(Sliding Window)


原因

这个问题可以归结为小包的问题,就是由于发送端和接收端上的处理不一致,导致网络上产生很多的小包,之前也介绍过避免网络上产生过多小包的措施,比如Nagle算法。在滑动窗口机制下,如果发送端和接收端速率很不一致,也会产生这种比较犯傻的状态:发送方发送的数据,只要一个大大的头部,携带数据很少。

对于接收端来讲,如果接收很慢,一次接收1个字节或者几个字节,这个时候接收端 缓冲区很快就会被填满,然后窗口通告为0字节,这个时候发送端停止发送,应用程序收上去1个字节后,发出窗口通告为1字节,发送方收到通告之后,发出1个字节的数据,这样周而复始,传输效率会非常低。

同时如果发送端程序一次发送一个字节,虽然窗口足够大,但是发送仍是一个字节一个字节的传输,效率很低


解决措施

其实我们现在比较少减少这种情况了,因为TCP协议栈已经做出了一些优化,通过一些之前的数据我们来看下,TCP协议栈做出的有些优化措施

对于接收端的优化

1. 接收端,窗口为0时,应用程序有收上去数据,但是并不立即会送窗口为1的通告,而是等待窗口大小满足一定的条件之后【能够接收一个最大报文,或者缓冲区的一半】,再来发送窗口通告,这样就不会产生小报文。

[Note:此处TCP-IP Guide书中有一种说法,如果一个窗口低于一半的Window Size,或者不够一个MSS,就直接通告窗口为0,不过此处下面的测试看,并没有按照这个原则,给出了一个384的窗口,可能会有优化,有待于确认]

如下图,通告0窗口之后,下一次窗口update就变成2048了, 其实这样并没有降低传输的效率,只是将不断的发送小包换成发送大包而已。

TCP-IP详解:糊涂窗口综合症(Silly Window syndrome)_第1张图片

2. Delay ACK,这个机制可以参考前面的文章,接收端不立即回,是否有数据回复进行捎带ACK,这个也能降低ACK的数量

3. 累计ACK,并不是每一个数据都回复ACK,可以多个数据段一起回复ACK

对于发送端的优化

解决发送端发送小包的问题,之前我们也有讨论过,TCP提供了Nagle算法

1. 对于从应用程序中接收到的第一块数据【没有任何等待ACK的包】,立即发送,一个字节的数据也需要发送出去

2. 对于后面的数据,协议栈会进行累计并等待,或者收到一个接收端发出一个ACK,或者累计到一个最大报文段,然后再发送数据

除了Nagle算法发送端还可以通过1个字节的数据来探测Windowsize的变化。

参考文章

1. http://blog.sina.com.cn/s/blog_eb7e42ca0101emsa.html
2. http://blog.chinaunix.net/uid-21237130-id-159734.html

你可能感兴趣的:(Networking)