滑动窗口的工作方式
窗口通知:
发送端维护发送窗口大小(不在包中传输),接收端在ACK中告知接收窗口大小;
发送窗口初始是发送缓冲区大小,接收窗口初始是接收缓冲区大小;缓冲区决定窗口的最大值;
发送窗口一般包括3个部分,从左到右:
- 已发送但未收到ACK的数据
- 可以立即发送的数据
- 空闲空间;
接收窗口就是接收缓冲区还剩多少空间,接收端处理能力越强,从缓冲区提取数据的速度就越快,接收窗口就越大;
发送窗口大小由接收窗口决定,发送端收到ACK后:
- 丢弃缓存中对应的数据,左沿向右移动;(收缩)
- 根据ACK告知的接收窗口看是否需要移动右沿;已发送未 ACK 的数据 + 可立即发送数据 + 空闲 = 接收窗口;(扩张)
作用:
- 提高效率,可以同时发送多个数据;
- 流量控制,适配不同处理能力的发送端和接收端
最优窗口大小(即发送/接收缓冲区大小)的计算:
- 尽量将两端之间的信道填满;
- 填满时,在信道上传输的数据 = 带宽(数据传输速度) * RTT,两个缓冲区应至少为这个大小
问题1:零窗口
接收端接收缓冲区满时,ACK中接收窗口为0,阻止发送端发送数据。发送方需要在接收方缓冲区空出来时得到通知,因此在发现零窗口后会进行窗口探测,即定时发送含有1字节内容的segment,通过其ACK查询接收方的接收窗口。
问题2:糊涂窗口综合症 (silly window syndrome)
现象:大量的小segment被传输(payload太小),造成网络利用率低下
发送端和接收端都有可能引起这种情况:
- 发送端每次只发送少量数据;
- 接收端的处理能力不够或应用层没有即时从接收缓冲区中取数据,接收窗口一直很小,发送端只能发小segment。
解决:
* 发送端: nagle算法 *
- 只针对
小segment
的stop-wait
协议,大segment不受影响; - 在前一个 小segment(小于MSS)的ack未到来前,缓存并合并其他要发送的小segment;
- 如果ack回来的很快,合并不了多少数据;
- ack通常是delayed,会导致数据发送的延时;不适合实时性的应用(可以取消);
- 目的是减少segment数目。
* 接收端: *
在接收端,当接收窗口小于一定阈值(如MSS一半)时,无论是数据确认ACK,还是对窗口探测的回应ACK,都宣告接收窗口为0,阻止发送端发送小报文段。
参考: