TCP窗口機制
TCP header中有一個Window Size字段,它其實是指接收端的窗口,即接收窗口。用來告知發送端自己所能接收的數據量,從而達到一部分流控的目的。
其實TCP在整個發送過程中,也在度量當前的網絡狀態,目的是為了維持一個健康穩定的發送過程,比如擁塞控制。因此,數據是在某些機制的控制下進行傳輸的,就是窗口機制。
窗口縮放因子(Window Scaling)
以前,window size最大為2的16次方,為65535,隨着寬帶不斷提高,65535字節已經小了,為了突破限制,便有了Window Size Scaling選項,假設window scale為7,也就是要將Window Size的值左移七位,即乘以128。window scale最大為14.
在整個雙方的交互過程中,發送方和接收方Window size scaling factor乘積因子必須保持不變,但是發送方的乘積因子和接收方的乘積因子可以不同,由各自決定。
在標志位中有SYN
的消息,會在選項中通知接收方,本端具體的放大因子,該消息本身不放大
上圖中的放大因子擴大了256倍,8212*256=2102272
發送窗口
(1)已經發送並且對端確認(Sent/ACKed)---------------發送窗外 緩沖區外
(2)已經發送但未收到確認數據(Sent/UnACKed)----- --發送窗內 緩沖區內
(3)允許發送但尚未防的數據(Unsent/Inside)-----------發送窗內 緩沖區內
(4)未發送暫不允許(Unsent/Outside)-------------------發送窗外 緩沖區內
2,3兩部分為發送窗口
接受窗口
對於TCP的接收方,在某一時刻在它的接收緩存內存在3種。“已接收”,“未接收准備接收”,“未接收並未准備接收”(由於ACK直接由TCP協議棧回復,默認無應用延遲,不存在“已接收未回復ACK”)。其中“未接收准備接收”稱之為接收窗口。
發送窗口與接收窗口關系
TCP是雙工的協議,會話的雙方都可以同時接收、發送數據。TCP會話的雙方都各自維護一個“發送窗口”和一個“接收窗口”。其中各自的“接收窗口”大小取決於應用、系統、硬件的限制(TCP傳輸速率不能大於應用的數據處理速率)。各自的“發送窗口”則要求取決於對端通告的“接收窗口”,要求相同。
滑動窗口
TCP並不是每一個報文段都會回復ACK的,可能會對兩個報文段發送一個ACK,也可能會對多個報文段發送1個ACK【累計ACK】,比如說發送方有1/2/3 3個報文段,先發送了2,3 兩個報文段,但是接收方期望收到1報文段,這個時候2,3報文段就只能放在緩存中等待報文1的空洞被填上,如果報文1,一直不來,報文2/3也將被丟棄,如果報文1來了,那么會發送一個ACK對這3個報文進行一次確認。
滑動窗口實現面向流的可靠性
最基本的傳輸可靠性來源於“確認重傳”機制。
TCP的滑動窗口的可靠性也是建立在“確認重傳”基礎上的。
發送窗口只有收到對端對於本段發送窗口內字節的ACK確認,才會移動發送窗口的左邊界。
接收窗口只有在前面所有的段都確認的情況下才會移動左邊界。當在前面還有字節未接收但收到后面字節的情況下,窗口不會移動,並不對后續字節確認。以此確保對端會對這些數據重傳。
滑動窗口的流控特性
TCP的滑動窗口是動態的,我們可以想象成小學常見的一個數學題,一個水池,體積V,每小時進水量V1,出水量V2。當水池滿了就不允許再注入了,如果有個液壓系統控制水池大小,那么就可以控制水的注入速率和量。這樣的水池就類似TCP的窗口。應用根據自身的處理能力變化,通過本端TCP接收窗口大小控制來對對對端的發送窗口流量限制。
應用程序在需要(如內存不足)時,通過API通知TCP協議棧縮小TCP的接收窗口。然后TCP協議棧在下個段發送時包含新的窗口大小通知給對端,對端按通知的窗口來改變發送窗口,以此達到減緩發送速率的目的。
滑動窗口動態調整
主要是根據接收端的接收情況,動態去調整Window Size,然后來控制發送端的數據流量
客戶端不斷快速發送數據,服務器接收相對較慢,看下實驗的結果
a. 包175,發送ACK攜帶WIN = 384,告知客戶端,現在只能接收384個字節
b. 包176,客戶端果真只發送了384個字節,Wireshark也比較智能,也宣告TCP Window Full
c. 包177,服務器回復一個ACK,並通告窗口為0,說明接收方已經收到所有數據,並保存到緩沖區,但是這個時候應用程序並沒有接收這些數據,導致緩沖區沒有更多的空間,故通告窗口為0, 這也就是所謂的零窗口,零窗口期間,發送方停止發送數據
d. 客戶端察覺到窗口為0,則不再發送數據給接收方
e. 包178,接收方發送一個窗口通告,告知發送方已經有接收數據的能力了,可以發送數據包了
f. 包179,收到窗口通告之后,就發送緩沖區內的數據了.
總結一點,就是接收端可以根據自己的狀況通告窗口大小,從而控制發送端的接收,進行流量控制