天天看點

TCP滑動視窗(發送視窗和接受視窗)

tcp header中有一個window size字段,它其實是指接收端的視窗,即接收視窗。用來告知發送端自己所能接收的資料量,進而達到一部分流控的目的。

其實tcp在整個發送過程中,也在度量目前的網絡狀态,目的是為了維持一個健康穩定的發送過程,比如擁塞控制。是以,資料是在某些機制的控制下進行傳輸的,就是視窗機制。

TCP滑動視窗(發送視窗和接受視窗)

以前,window size最大為2的16次方,為65535,随着寬帶不斷提高,65535位元組已經小了,為了突破限制,便有了window size scaling選項,假設window scale為7,也就是要将window size的值左移七位,即乘以128。window scale最大為14.

在整個雙方的互動過程中,發送方和接收方window size scaling factor乘積因子必須保持不變,但是發送方的乘積因子和接收方的乘積因子可以不同,由各自決定。

TCP滑動視窗(發送視窗和接受視窗)

在标志位中有<code>syn</code>的消息,會在選項中通知接收方,本端具體的放大因子,該消息本身不放大

TCP滑動視窗(發送視窗和接受視窗)

上圖中的放大因子擴大了256倍,8212*256=2102272

TCP滑動視窗(發送視窗和接受視窗)

(1)已經發送并且對端确認(sent/acked)---------------發送窗外 緩沖區外

(2)已經發送但未收到确認資料(sent/unacked)----- --發送窗内 緩沖區内

(3)允許發送但尚未防的資料(unsent/inside)-----------發送窗内 緩沖區内

(4)未發送暫不允許(unsent/outside)-------------------發送窗外 緩沖區内

2,3兩部分為發送視窗

對于tcp的接收方,在某一時刻在它的接收緩存記憶體在3種。“已接收”,“未接收準備接收”,“未接收并未準備接收”(由于ack直接由tcp協定棧回複,預設無應用延遲,不存在“已接收未回複ack”)。其中“未接收準備接收”稱之為接收視窗。

tcp是雙工的協定,會話的雙方都可以同時接收、發送資料。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,收到視窗通告之後,就發送緩沖區内的資料了.

TCP滑動視窗(發送視窗和接受視窗)

總結一點,就是接收端可以根據自己的狀況通告視窗大小,進而控制發送端的接收,進行流量控制

tcp 滑動視窗(發送視窗和接收視窗)

解析tcp之滑動視窗(動畫示範)

tcp-ip詳解:滑動視窗(sliding window)