TCP滑動窗口和擁塞控制


 

滑動窗口協議(Sliding Window Protocol),屬於TCP協議的一種應用,用於網絡數據傳輸時的流量控制,以避免擁塞的發生。該協議允許發送方在停止並等待確認前發送多個數據分組。由於發送方不必每發一個分組就停下來等待確認,因此該協議可以加速數據的傳輸,提高網絡吞吐量。

 

TCP通過滑動窗口的概念來進行流量控制。設想在發送端發送數據的速度很快而接收端接收速度卻很慢的情況下,為了保證數據不丟失,顯然需要進行流量控制, 協調好通信雙方的工作節奏。所謂滑動窗口,可以理解成接收端所能提供的緩沖區大小。TCP利用一個滑動的窗口來告訴發送端對它所發送的數據能提供多大的緩 沖區。由於窗口由16位bit所定義,所以接收端TCP 能最大提供65535個字節的緩沖。由此,可以利用窗口大小和第一個數據的序列號計算出最大可接收的數據序列號。 

 

滑動窗口本質上是描述接受方的TCP數據報緩沖區大小的數據,發送方根據這個數據來計算自己最多能發送多長的數據。如果發送方收到接受方的窗口大小為0的TCP數據報,那么發送方將停止發送數據,等到接受方發送窗口大小不為0的數據報的到來。 

 

窗口合攏:當窗口從左邊向右邊靠近的時候,這種現象發生在數據被發送和確認的時候。   
       窗口張開:當窗口的右邊沿向右邊移動的時候,這種現象發生在接受端處理了數據以后。   
        窗口收縮:當窗口的右邊沿向左邊移動的時候,這種現象不常發生。   
        TCP就是用這個窗口,慢慢的從數據的左邊移動到右邊,把處於窗口范圍內的數據發送出去(但不用發送所有,只是處於窗口內的數據可以發送。)。這就是窗口的意義。窗口的大小是可以通過socket來制定的,4096並不是最理想的窗口大小,而16384則可以使吞吐量大大的增加。

 

A————C————B

 

如上圖,A與B之間建立TCP連接,滑動窗口實現有兩個作用: 

 

由於對稱性,只考慮A端發送窗口和B端接收窗口,有如下兩個作用   

 

1、B端來不及處理接收數據(控制不同速率主機間的同步),這時,A通過B端通知的接收窗口而減緩數據的發送。   
2、B端來得及處理接收數據,但是在A與B之間某處如C,使得AB之間的整體帶寬性能較差,此時,A端根據擁塞處理策略(慢啟動,加倍遞減和緩慢增加)來更新窗口,以決定數據的發送。   

 

與固定大小的滑窗協議相比,TCP采用可變大小的滑窗協議是為了取得更好的性能。   

 

TCP是一個廣域網協議,而廣域網環境下的路由器和主機,各自有着不同的性能和處理能力,在這種情況下,采用固定窗口大小的滑窗協議會引起性能上的損失。TCP規定窗口的大小是由接收方通告的,通過采取慢啟動和擁塞避免算法等機制來使帶寬和性能取得最佳。

 

1. “窗口”對應的是一段可以被發送者發送的字節序列,其連續的范圍稱之為“窗口”;

 

2. “滑動”則是指這段“允許發送的范圍”是可以隨着發送的過程而變化的,方式就是按順序“滑動”。

 

    1. TCP協議的兩端分別為發送者A和接收者B,由於是全雙工協議,因此A和B應該分別維護着一個獨立的發送緩沖區和接收緩沖區,由於對等性(A發B收和B發A收),我們以A發送B接收的情況作為例子;

    2.         發送窗口是發送緩存中的一部分,是可以被TCP協議發送的那部分,其實應用層需要發送的所有數據都被放進了發送者的發送緩沖區;

    3.       發送窗口中相關的有四個概念:已發送並收到確認的數據(不再發送窗口和發送緩沖區之內)、已發送但未收到確認的數據(位於發送窗口之中)、允許發送但尚未發送的數據以及發送窗口外發送緩沖區內暫時不允許發送的數據

    4.        每次成功發送數據之后,發送窗口就會在發送緩沖區中按順序移動,將 新的數據包含到窗口中准備發送;

 

TCP建立連接的初始,B會告訴A自己的接收窗口大小,比如為‘20’:字節31-50為發送窗口。

 

 

根據B給出窗口值,A構造自己的窗口

 

A發送11個字節后,發送窗口位置不變,B接收到了亂序的數據分組:

 

 

A發了11個字節數據

 

只有當A成功發送了數據,即發送的數據得到了B的確認之后,才會移動滑動窗口離開已發送的數據;同時B則確認連續的數據分組,對於亂序的分組則先接收下來,避免網絡重復傳遞:

 

 

A收到新的確認號,窗口向前滑動

 

 

發送窗口內的序號都屬於已發送但未被確認

 

所謂流量控制,主要是接收方傳遞信息給發送方,使其不要發送數據太快,是一種端到端的控制。主要的方式就是返回的ACK中會包含自己的接收窗口的大小,並且利用大小來控制發送方的數據發送:

 

 

這里面涉及到一種情況,如果B已經告訴A自己的緩沖區已滿,於是A停止發送數據;等待一段時間后,B的緩沖區出現了富余,於是給A發送報文告訴A我的rwnd大小為400,但是這個報文不幸丟失了,於是就出現A等待B的通知||B等待A發送數據的死鎖狀態。為了處理這種問題,TCP引入了持續計時器(Persistence timer),當A收到對方的零窗口通知時,就啟用該計時器,時間到則發送一個1字節的探測報文,對方會在此時回應自身的接收窗口大小,如果結果仍未0,則重設持續計時器,繼續等待。

 


 

 

 

傳遞效率
     一個顯而易見的問題是:單個發送字節單個確認,和窗口有一個空余即通知發送方發送一個字節,無疑增加了網絡中的許多不必要的報文(請想想為了一個字節數據而添加的40字節頭部吧!),所以我們的原則是盡可能一次多發送幾個字節,或者窗口空余較多的時候通知發送方一次發送多個字節。對於前者我們廣泛使用Nagle算法,即:
*1. 若發送應用進程要把發送的數據逐個字節地送到TCP的發送緩存,則發送方就把第一個數據字節先發送出去,把后面的字節先緩存起來;
*2. 當發送方收到第一個字節的確認后(也得到了網絡情況和對方的接收窗口大小),再把緩沖區的剩余字節組成合適大小的報文發送出去;
*3. 當到達的數據已達到發送窗口大小的一半或以達到報文段的最大長度時,就立即發送一個報文段;
     對於后者我們往往的做法是讓接收方等待一段時間,或者接收方獲得足夠的空間容納一個報文段或者等到接受緩存有一半空閑的時候,再通知發送方發送數據。

 

擁塞控制
     網絡中的鏈路容量和交換結點中的緩存和處理機都有着工作的極限,當網絡的需求超過它們的工作極限時,就出現了擁塞。擁塞控制就是防止過多的數據注入到網絡中,這樣可以使網絡中的路由器或鏈路不致過載。常用的方法就是:
1. 慢開始、擁塞控制
2. 快重傳、快恢復
     一切的基礎還是慢開始,這種方法的思路是這樣的:
-1. 發送方維持一個叫做“擁塞窗口”的變量,該變量和接收端口共同決定了發送者的發送窗口;
-2. 當主機開始發送數據時,避免一下子將大量字節注入到網絡,造成或者增加擁塞,選擇發送一個1字節的試探報文;
-3. 當收到第一個字節的數據的確認后,就發送2個字節的報文;
-4. 若再次收到2個字節的確認,則發送4個字節,依次遞增2的指數級;
-5. 最后會達到一個提前預設的“慢開始門限”,比如24,即一次發送了24個分組,此時遵循下面的條件判定:
*1. cwnd < ssthresh, 繼續使用慢開始算法;
*2. cwnd > ssthresh,停止使用慢開始算法,改用擁塞避免算法;
*3. cwnd = ssthresh,既可以使用慢開始算法,也可以使用擁塞避免算法;
-6. 所謂擁塞避免算法就是:每經過一個往返時間RTT就把發送方的擁塞窗口+1,即讓擁塞窗口緩慢地增大,按照線性規律增長;
-7. 當出現網絡擁塞,比如丟包時,將慢開始門限設為原先的一半,然后將cwnd設為1,執行慢開始算法(較低的起點,指數級增長);

 

 

上述方法的目的是在擁塞發生時循序減少主機發送到網絡中的分組數,使得發生擁塞的路由器有足夠的時間把隊列中積壓的分組處理完畢。慢開始和擁塞控制算法常常作為一個整體使用,而快重傳和快恢復則是為了減少因為擁塞導致的數據包丟失帶來的重傳時間,從而避免傳遞無用的數據到網絡。快重傳的機制是:
-1. 接收方建立這樣的機制,如果一個包丟失,則對后續的包繼續發送針對該包的重傳請求;
-2. 一旦發送方接收到三個一樣的確認,就知道該包之后出現了錯誤,立刻重傳該包;
-3. 此時發送方開始執行“快恢復”算法:
*1. 慢開始門限減半;
*2. cwnd設為慢開始門限減半后的數值;
*3. 執行擁塞避免算法(高起點,線性增長);

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM