关于滑动窗口的一些理解
最近在学习TCP协议,在看到关于滑动窗口的理论时,找了很多博客,发现都太好理解
现在根据自己的理解对滑动窗口简单总结如下,后续再补充详细的说明。
1、滑动窗口包括发送窗口和接收窗口,client和server每个连接都有一个发送窗口和一个接收窗口,因为TCP是全双工通信。
2、窗口大小的调整是通过调整窗口左边沿、窗口右边沿调整窗口大小的,并且不管接收窗口还是发送窗口,左、右边沿只能向右滑动。由于窗口边沿只能向右滑动,因此窗口宽度减小只能是左边沿滑动,窗口宽度增大只能是右边沿滑动。
3、接收侧边沿移动规则:
定义应用从缓存区取出的包为地址为AppLastRead,最大连续包所在地址为NextExpected,发给发送侧Ack所指向的地址,缓存作为一个循环队列的大小为BufferSize,滑动窗口左边沿地址为WindowLeft,窗口右边沿地址为WindowRight,则窗口边沿计算公式如下:
WindowLeft = NextExpected
WindowRight = AppLastRead+BufferSize
发送窗口大小Window = WindowRight-WindowLeft
NextExpected指向的包序号作为Ack,Window填入TCP报文window字段,一起相应给发送端。
4、发送侧边沿移动规则:
定义已发送并且收到ACK的最大包对应的地址为Acked,已发送但是未收到Ack的包的地址为Sent,已在窗口内暂时未发送的包的最大地址为WaitSend,窗口右侧不能发送的包的最大地址为AppWrite
则WindowLeft = Acked
WindowRight = WindowLeft+Window,Window为从TCP报文提取的window字段,也就是接收发给发送侧的
而Window = Window(接收侧) = WindowRight-WindowLeft = WindowRight(接收侧)-NextExpected
因此WindowRight = WindowLeft+Window
= Acked+WindowRight(接收侧)-NextExpected
=( Acked - NextExpected)+WindowRight(接收侧)
Acked-NextExpected是个常数,因此WindowRight(发送侧) = C + WindowRight(接收侧)
5、综合3、4点可知,发送侧的窗口受接收侧来调节,左边沿受接收侧左边沿控制,右边沿受接收侧窗口大右边沿控制,因此在很多博客中才会说,发送滑动窗口闭合(左边沿移动)往往是收到了新的ACK,发送滑动窗口扩张(右边沿移动)往往是接收侧应用读取了缓存中的数据导致。