最近在學習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,發送滑動窗口擴張(右邊沿移動)往往是接收側應用讀取了緩存中的數據導致。