《計算機網路微課堂》5-5 TCP的擁塞控制

peterjxl發表於2024-05-29

本節課我們介紹 TCP 的擁塞控制,首先來看擁塞控制的基本概念:

  • 在某段時間,若對網路中某一資源的需求超過了該資源所能提供的可用部分,網路效能就要變壞,這種情況就叫做擁塞
  • 在計算機網路中的鏈路容量,交換節點中的快取和處理機等都是網路的資源,若出現擁塞而不進行控制,整個網路的吞吐量將隨輸入負載的增大而下降
  • 我們使用下圖來說明擁塞控制的作用。橫座標是輸入負載,代表單位時間內輸入給網路的分組數量,縱座標是吞吐量,代表單位時間內從網路輸出的分組數量,具有理想擁塞控制的網路,在吞吐量達到飽和之前,網路吞吐量應等於所輸入的負載,故吞吐量曲線是 45 度的斜線,但當輸入負載超過某一限度時,由於網路資源受限,吞吐量就不再增長,而保持水平線,也就是吞吐量達到飽和,這就表明輸入的負載中有一部分損失掉了。例如輸入到網路中的某些分組,被某個節點丟棄了
  • 雖然如此,在這種理想的擁塞控制作用下,網路的吞吐量仍然維持在其所能達到的最大值。然而實際的網路情況就很不同了。我們再來看這條吞吐量曲線,隨著輸入負載的增大,網路吞吐量的增長率逐漸減小,也就是在網路吞吐量還未達到飽和時,就已經有一部分的輸入分組被丟棄了。當網路的吞吐量明顯的小於理想的吞吐量時,網路就進入了輕度擁塞的狀態
  • 更值得注意的是,當輸入負載到達某一數值時,網路的吞吐量反而隨輸入負載的增大而減小,這時網路就要進入了擁塞狀態,當輸入負載繼續增大到某一數值時,網路的吞吐量就要減小為零,此時網路就要無法工作了,這就是所謂的死鎖。因此進行擁塞控制是非常有必要的。實際的擁塞控制曲線應該儘量接近理想的擁塞控制曲線

接下來我們介紹 TCP 的 4 種擁塞控制演算法,他們分別是慢開始,擁塞避免,快重傳,快恢復。我們來舉例說明 TCP 這 4 種擁塞控制演算法的基本原理,為了集中精力討論擁塞控制,我們假定如下條件:

  • 一資料是單方向傳送的,而另一個方向只傳送確認
  • 二接收方總是有足夠大的快取空間,因而傳送方傳送視窗的大小僅由網路的擁塞程度來決定
  • 三以 TCP 最大報文段 MSS 的個數為討論問題的單位,而不是以位元組為單位

假設這是 TCP 的傳送方和接收方,傳送方給接收方傳送 TCP 資料包文段,接收方收到後給傳送方傳送 TCP 確認報文段:

  • 傳送方要維護一個叫做擁塞視窗 cwnd 的狀態變數,其值取決於網路的擁塞程度,並且動態變化

    • 擁塞視窗的維護原則是隻要網路沒有出現擁塞,擁塞視窗就再增大一些,但只要網路出現擁塞,擁塞視窗就減小一些
    • 判斷出現網路擁塞的依據是沒有按時收到應當到達的確認報文段,也就是發生了超時重傳
  • 傳送方將擁塞視窗作為傳送視窗 swnd,也就是傳送視窗等於擁塞視窗 swnd=cwnd

  • 傳送方還需要維護一個叫做慢開始門線的狀態變數 ssthresh

    • 當擁塞視窗小於慢開始門線時,使用慢開始演算法
    • 當擁塞視窗大於慢開始門限時停止使用慢開始演算法,而改用擁塞避免演算法
    • 當擁塞視窗等於慢開始門限時,既可以使用慢開始演算法,也可以使用擁塞避免演算法

首先來看慢開始演算法,為了更清楚的顯示出擁塞控制過程,我們還可以繪製這樣一幅擁塞視窗隨傳輸輪次變化的圖,橫座標為傳輸輪次,傳輸輪次是指傳送方給接收方傳送資料包文段後,接收方給傳送方發回相應的確認報文段。一個傳輸輪次所經歷的時間,其實就是往返時間。請注意往返時間並非是恆定的數值,使用傳輸輪次是為了強調把擁塞視窗所允許傳送的報文段都連續傳送出去,並收到了對已傳送的最後一個報文段的確認。

縱座標是擁塞視窗,它會隨網路擁塞程度以及所使用的擁塞控制演算法動態變化。

在 TCP 雙方建立邏輯連線關係時,擁塞視窗的值被設定為 1,我們在圖上標出傳輸輪次 0 時的擁塞視窗值為一,另外還需設定慢開始門線的初始值,本例採用 16,我們也將它在圖中標出,在執行慢開始演算法時,傳送方每收到一個對新報文段的確認時,就把擁塞視窗值加一,然後開始下一輪的傳輸,當擁塞視窗值增長到慢開始門限值時,就要改為執行擁塞避免演算法。

由於傳送方當前的擁塞視窗值是 1,而傳送視窗值等於擁塞視窗值,因此傳送方當前只能傳送一個 TCP 資料包文段,換句話說,擁塞視窗值是幾,就能傳送幾個資料包文段,如圖所示傳送方傳送 0 號資料包文段,接收方收到後給傳送方發回對 0 號報文段的確認報文段,傳送方收到該確認報文段後,將擁塞視窗值加一增大到二,我們在圖中標出該值,這意味著傳送方現在可以傳送 1~2 號共兩個資料包文段

由於傳送方當前的擁塞視窗值是 1,而傳送視窗值等於擁塞視窗值,因此傳送方當前只能傳送一個 TCP 資料包文段,換句話說,擁塞視窗值是幾,就能傳送幾個資料包文段,如圖所示傳送方傳送 0 號資料包文段,接收方收到後給傳送方發回對 0 號報文段的確認報文段,傳送方收到該確認報文段後,將擁塞視窗值加一增大到二,我們在圖中標出該值,這意味著傳送方現在可以傳送 1~2 號共兩個資料包文段

接收方收到後給傳送方發回,對 1~2 號報文段的確認報文段。

傳送方收到後將擁塞視窗值加 2 增大到 4。我們在圖中標出該值,傳送方現在可以傳送 3~6 號共 4 個資料包文段,接收方收到後給傳送方發回,對 3~6 號報文段的確認報文段,傳送方收到後將擁塞視窗值加四增大到 8。

我們在圖中標出該值傳送方現在可以傳送 7~14 號,共 8 個資料包文段,接收方收到後給傳送方發回,對 7~14 號報文段的確認報文段,傳送方收到後將擁塞視窗值加 8 增大到 16,我們在圖中標出該值,傳送方當前的擁塞視窗值已經增大到了慢開始門限值之後,我們要改用擁塞避免演算法,也就是每個傳輸輪次結束後,擁塞視窗值只能線性加一,而不像慢開始演算法那樣,每個傳輸輪次結束後,擁塞視窗值按指數規律增長。

傳送方現在可以傳送 15~30 號,共 16 個資料包文段,接收方收到後給傳送方發回,對 15~30 號報文段的確認報文段,傳送方收到後將擁塞視窗值加一增大到 17。我們在圖中標出該值現在可以傳送 31~47 號,共 17 個資料包文段,接收方收到後給傳送方發回,對 31~47 號報文段的確認報文段,傳送方收到後將擁塞視窗值加一增大到 18,我們在圖中標出該值:

隨著傳輸輪次的增加,擁塞視窗值每輪次都線性加一,例如當前擁塞穿口值增加到了 24,傳送方現在可以傳送 171~194 號,共 24 個資料包文段。假設這 24 個資料包文段在傳輸過程中丟失了幾個,這必然會造成傳送方對這些丟失報文段的超時重傳。傳送方以此判斷網路很可能出現了擁塞,需要進行以下工作。

1.將慢開始門限值,更新為發生擁塞時擁塞視窗值的一半,網路發生擁塞時的擁塞視窗值是 24,因此更新慢開始門限值為該值的一半,即 12 如圖所示:

2.將擁塞視窗值減小為一,並重新開始執行慢開始演算法,當慢開始執行到擁塞視窗值增大到新的慢開始門限值時,就要停止使用慢開始演算法,轉而執行擁塞避免演算法,如圖所示:

透過本例可以看出,TCP 傳送方一開始使用慢開始演算法,讓擁塞視窗值從一開始按指數規律增大,當擁塞視窗值增大到慢開始門線值時停止使用慢開始演算法,轉而執行擁塞避免演算法,讓擁塞視窗值按線性加一的規律增大。當發生超時重傳時,就要判斷網路很可能出現了擁塞,採取相應的措施,一方面將慢開始門限值,更新為發生擁塞時擁塞視窗值的一半,另一方面將擁塞視窗值減小為一,並重新開始執行慢開始演算法。

擁塞視窗值又從一開始按指數規律增大,當增大到了新的慢開始門限值時,停止使用慢開始演算法,轉而執行用在避免演算法,讓擁塞視窗值按線性加一的規律增大。

需要注意的是慢開始是指一開始向網路注入的報文段少,而並不是指擁塞視窗值增長速度慢。

擁塞避免,也並非指完全能夠避免營塞。而是隻在擁塞避免階段將擁塞視窗值控制為按線性規律增長,使網路比較不容易出現擁塞。

慢開始和擁塞避免是 1988 年就提出的 TCP 擁塞控制演算法,也就是 TCP 的 Tahoe 版本,1990 年又增加了兩個新的擁塞控制演算法,以便改進 TCP 的效能,這就是快重傳和快恢復,被稱為 TCP 的 Reno 版本。有時個別報文段會在網路中丟失,但實際上網路並未發生擁塞,這將導致傳送方超時重傳,並誤認為網路發生了擁塞。

例如在之前的例子中,當擁塞視窗值增大到 24 時,發生了超時重傳,而網路此時並沒有發生擁塞,但是傳送方卻誤認為網路發生了擁塞,於是傳送方把擁塞視窗值減小為一併錯誤的啟動慢開始演算法,因而降低了傳輸效率。

採用快重傳演算法,可以讓傳送方儘早知道發生了個別報文段的丟失。所謂快重傳是傳送方儘快進行重傳,而不是等超時重傳計時器超時再重傳:

  • 這就要求接收方不要等待自己傳送資料時才進行捎帶確認,而是要立即傳送確認
  • 即使收到了失序的報文段,也要立即傳送,對已收到的報文段的重複確認
  • 傳送方一旦收到三個連續的重複確認,就將相應的報文段立即重傳,而不是等該報文段的重傳計時器超時再重傳

我們來舉例說明快重傳演算法:

  • 傳送方傳送 1 號資料包文段,接收方收到後給傳送方發回,對 1 號報文段的確認,在該確認報文段到達傳送方之前,傳送方還可以將傳送視窗內的 2 號資料包文段傳送出去
  • 接收方收到後給傳送方發回對 2 號報文段的確認
  • 在該確認報文段到達傳送方之前,傳送方還可以將傳送視窗內的 3 號資料包文段傳送出去,但該報文段丟失了,接收方自然不會給傳送方發回針對該報文段的確認
  • 傳送方還可以將傳送視窗內的 4 號資料包文段傳送出去,接收方收到後,發現這不是按序到達的報文段,因此給傳送方發回,針對 2 號報文段的重複確認,表明我現在希望收到的是三號報文段,但是我沒有收到三號報文段,而是收到了未按序到達的報文段
  • 傳送方還可以將傳送視窗內的 5 號資料包文段傳送出去,接收方收到後發現這不是按序到達的報文段,因此給傳送方發回針對 2 號報文段的重複確認
  • 傳送方還可以將傳送視窗內的 6 號資料包文段傳送出去,接收方收到後發現這不是按需到達的報文段,因此給傳送方發回針對 2 號報文段的重複確認,至此傳送方會收到三個連續的對二號報文段的重複確認,就要立即重傳三號報文段
  • 接收方收到後給傳送方發回針對 6 號報文段的確認,表明序號到六為止的報文段都正確接收了,這樣就不會造成對三號報文段的超時重傳,而是提早進行了重傳
  • 對於個別丟失的報文段,傳送方不會出現超時重傳,也就不會誤認為出現了擁塞,而錯誤的降低擁塞視窗值為最小值一,使用快重傳可以使整個網路的吞吐量提高約 20%

再來看快恢復演算法,傳送方一旦收到三個重複確認,就知道現在只是丟失了個別的報文段,於是不啟動慢開始演算法,而是執行快恢復演算法。

傳送方將慢開始門限值和擁塞視窗值調整為當前視窗值的一半,開始執行擁塞避免演算法。

也有的快恢復實現,是把快恢復開始時的擁塞視窗值再增大一些,也就是等於新的慢開始門限值 +3 。這樣做的理由是:

  • 既然傳送方收到三個重複的確認,就要表明有三個資料包文段已經離開了網路
  • 這三個報文段不再消耗網路資源,而是停留在接收方的接收快取中
  • 可見現在網路中不是堆積的報文段,而是減少了三個報文段,因此可以適當把用塞視窗值擴大一些

接下來我們給出 TCP 擁塞視窗值,在擁塞控制時的變化情況舉例,裡面包含了 TCP 擁塞控制的 4 種演算法,TCP 傳送方一開始使用慢開始演算法,讓擁塞視窗值從一開始按指數規律增大,當增大到慢開始門線初始值時,停止使用慢開始演算法,轉而執行擁塞避免演算法,讓擁塞視窗值按線性加 1 的規律增大。

當發生超時重傳時,就要判斷網路可能出現了擁塞,採取相應的措施,一方面將慢開始門限值,更新為發生擁塞時擁塞視窗值的一半,另一方面將擁塞視窗值減小為一,並重新開始執行慢開始演算法。

擁塞視窗值又從一開始按指數規律增大,當增大到了新的慢開始門限值時,停止使用慢開始演算法,轉而執行擁塞避免演算法,讓擁塞視窗值按線性加一的規律增大。當傳送方收到三個重複的確認時,就要進行快重傳和快恢復,也就是更新慢開始門限值為當前擁塞視窗值的一半,並將擁塞視窗值也取為新的慢開始門限值,轉而執行擁塞避免演算法,讓擁塞視窗值按線性交易的規律增大。

練習題,這是計算機專業考研全國統考計算機網路部分 2009 年的題 39,答案是選項 C 根據題意,我們可以畫出傳送方擁塞視窗值,隨傳輸輪次的變化圖,這是慢開始部分,當擁塞視窗值增大到慢開始門線的初始值時停止使用慢開始演算法,轉而執行擁塞避免演算法。根據題意,當擁塞視窗值增大到 16K 位元組時,發生了超時重傳,於是將慢開始門限值更新為當前用塞視窗值的一半,並將用塞視窗值減小為 1KB,並重新開始執行慢開始演算法。當擁塞視窗值增大到新的慢開始門限值時,停止使用慢開始演算法,轉而執行擁塞避免演算法。可以看到該處就是題目所問的,在超時後的 4 個往返時間後,也就是在超時後的 4 個傳輸輪次結束後,擁塞視窗值增長到 9K 位元組。

需要說明的是題目並未給出慢開始門限值的初始值,因此這部分傳輸輪次只是示意,目的是為了讓大家能夠更好的理解

本節課的內容小結如下:

相關文章