1、
滑动窗口其实是一种协议,它主要提供两个作用,一是提供TCP的可靠性,二是提供TCP的流量控制特性,我感觉因为其协议动作特征类似窗口在移动所以称为滑动窗口。如图,从TCP首部可以看到滑动窗口的大小占16位,故其最大为2^16-1即65535个字节,另外在TCP的选项字段中还包含了一个TCP窗口扩大因子,窗口扩大因子用来扩大TCP窗口,可把原来16bit的窗口,扩大为31bit。
2、
滑动窗口可以分为发送窗口和接收窗口,因为TCP是双工的协议,所以TCP会话的双方都各自维护一个“发送窗口”和一个“接收窗口”。“接收窗口”的大小取决于应用、系统、硬件的限制,“发送窗口”是根据连接时对端告知的其“接收窗口”大小来构造的。
对于TCP会话的发送方,任何时候在其发送缓存内的数据都可以分为4类,“已经发送并得到对端ACK的”,“已经发送但还未收到对端ACK的”,“未发送且对端允许发送的”,“未发送但对端不允许发送”。其中“已经发送但还未收到对端ACK的”和“未发送但对端允许发送的”这两部分数据称之为发送窗口。
对于TCP的接收方,在某一时刻在它的接收缓存内存在3种。“已接收”,“未接收准备接收”,“未接收但还未准备接收”(由于ACK直接由TCP协议栈回复,默认无应用延迟,不存在“已接收未回复ACK”)。其中“未接收准备接收”称之为接收窗口。
如下图一,中间的两部分称为发送窗口。而当收到接收方新的ACK对于发送窗口中后续字节的确认时,窗口滑动,如下图二,当收到ACK=36时窗口滑动。
图一:
图二:
3、
我们经常说TCP协议是一种可靠的、面向流的传输协议,其可靠性和流控特性就是通过滑动窗口实现的。
滑动窗口的传输可靠性是建立在“确认重传”基础上的:发送窗口只有收到对端对于本段发送窗口内字节的ACK确认,才会移动发送窗口的左边界,接收窗口只有在前面所有的段都确认了的情况下才会移动左边界。当在前面还有字节未接收但收到后面字节的情况下,窗口不会移动,并不对后续字节确认,以此确保对端会对这些数据重传。
滑动窗口的流控特性就是通过本端TCP接收窗口大小控制来对对端的发送窗口流量限制:应用程序在需要时,通过API通知TCP协议栈缩小TCP的接收窗口。然后TCP协议栈在下个段发送时包含新的窗口大小通知给对端,对端按通知的窗口来改变发送窗口,以此达到减缓发送速率的目的。这其中有两个要点需要掌握,一个是“流量控制”,一个是“传输效率”。
所谓"流量控制",主要是接收方传递信息给发送方,使其不要发送数据太快,是一种端到端的控制。主要的方式就是返回的ACK中会包含自己的接收窗口的大小,并且利用大小来控制发送方的数据发送。
对于"传递效率"来说,一个显而易见的问题是:单个发送字节单个确认和窗口有一个空余即通知发送方发送一个字节的两种情况,这无疑增加了网络中的许多不必要的报文(请想想为了一个字节数据而添加的40字节头部吧!),所以我们的原则是尽可能一次多发送几个字节,或者窗口空余较多的时候通知发送方一次发送多个字节。对于前者我们广泛使用Nagle算法,对于后者我们往往的做法是让接收方等待一段时间,或者接收方获得足够的空间容纳一个报文段,或者等到接受缓存有一半空闲的时候,再通知发送方发送数据。
转载出处:https://my.oschina.net/xinxingegeya/blog/485650
http://www.cnblogs.com/woaiyy/p/3554182.html