1. 程式人生 > >TCP協議的流量控制和擁塞控制

TCP協議的流量控制和擁塞控制

流量控制與擁塞控制可是TCP協議的兩大特點,這兩者是有一定關聯的。 流量控制就是讓傳送方的發生速率不要太快,要讓接收方來的及接收,不然會找出資料溢位丟失。流量控制是利用滑動視窗機制實現的。

1.流量控制——滑動視窗

TCP採用大小可變的滑動視窗進行流量控制,視窗大小的單位是位元組。 傳送視窗在連線建立時由雙方商定。但在通訊的過程中,接收端可根據自己的資源情況,隨時動態地調整對方的傳送視窗上限值(可增大或減小)。 為什麼要設定視窗? 我們可以把視窗理解為緩衝區(但是有些視窗和緩衝區又不太一樣)。 如果沒有這些“視窗”,那麼TCP沒傳送一段資料後都必須等到接收端確認後才能傳送下一段資料(否則會出現接收端資料來不及處理,資料丟失的情況),這樣做的話TCP傳輸的效率實在是太低了。
解決的辦法就是在傳送端等待確認的時候繼續傳送資料,假設傳送到第X個數據段是收到接收端的確認資訊,如果X在可接受的範圍內那麼這樣做也是可接受的。這就是視窗(緩衝區)引入的緣由。 1.1 視窗 (1)接收端視窗 rwnd      接收端緩衝區大小。接收端將此視窗值放在 TCP 報文的首部中的視窗欄位,傳送給傳送端。 (2) 擁塞視窗 cwnd (congestion window)     傳送端緩衝區大小 (3)傳送視窗swnd              傳送視窗的上限值 = Min [rwnd, cwnd] 當 rwnd < cwnd 時,是接收端的接收能力限制傳送視窗的最大值。
當 cwnd < rwnd 時,則是網路的擁塞限制傳送視窗的最大值。  1.2 滑動視窗 傳送端已傳送了 400 位元組的資料,但只收到對前 200 位元組資料的確認,同時視窗大小不變。還可傳送 300 位元組。

傳送端收到了對方對前 400 位元組資料的確認,但對方通知傳送端必須把視窗減小到 400 位元組。現在傳送端最多還可傳送 400 位元組的資料。 下面是另一個例子說明利用滑動視窗機制進行流量控制:

  設A向B傳送資料。在連線建立時,B告訴了A:“我的接收視窗是 rwnd = 400 ”(這裡的 rwnd 表示 receiver window) 。因此,傳送方的傳送視窗不能超過接收方給出的接收視窗的數值。請注意,TCP的視窗單位是位元組,不是報文段。TCP連線建立時的視窗協商過程在圖中沒有顯示出來。再設每一個報文段為100位元組長,而資料報文段序號的初始值設為1。大寫ACK表示首部中的確認位ACK,小寫ack表示確認欄位的值ack。

    從圖中可以看出,B進行了三次流量控制。第一次把視窗減少到 rwnd = 300 ,第二次又減到了 rwnd = 100 ,最後減到 rwnd = 0 ,即不允許傳送方再發送資料了。這種使傳送方暫停傳送的狀態將持續到主機B重新發出一個新的視窗值為止。B向A傳送的三個報文段都設定了 ACK = 1 ,只有在ACK=1時確認號欄位才有意義。

    TCP為每一個連線設有一個持續計時器(persistence timer)。只要TCP連線的一方收到對方的零視窗通知,就啟動持續計時器。若持續計時器設定的時間到期,就傳送一個零視窗控測報文段(攜1位元組的資料),那麼收到這個報文段的一方就重新設定持續計時器。

1.3 必須考慮傳輸速率

    可以用不同的機制來控制TCP報文段的傳送時機。如: <1>. TCP維持一個變數,它等於最大報文段長度MSS。只要快取中存放的資料達到MSS位元組時,就組裝成一個TCP報文段傳送出去。<2>. 由傳送方的應用程序指明要求傳送報文段,即TCP支援的推送( push )操作。<3>. 傳送方的一個計時器期限到了,這時就把已有的快取資料裝入報文段(但長度不能超過MSS)傳送出去。

    Nagle演算法:若傳送應用程序把要傳送的資料逐個位元組地送到TCP的傳送快取,則傳送方就把第一個資料位元組先發送出去,把後面到達的資料位元組都快取起來。當傳送方接收對第一個資料字元的確認後,再把傳送快取中的所有資料組裝成一個報文段再發送出去,同時繼續對隨後到達的資料進行快取。只有在收到對前一個報文段的確認後才繼續傳送下一個報文段。當資料到達較快而網路速率較慢時,用這樣的方法可明顯地減少所用的網路頻寬。Nagle演算法還規定:當到達的資料已達到 傳送視窗大小的一半或已達到報文段的最大長度時,就立即傳送一個報文段。

    另,糊塗視窗綜合證: TCP接收方的快取已滿,而互動式的應用程序一次只從接收快取中讀取1位元組(這樣就使接收快取空間僅騰出1位元組),然後向傳送方傳送確認,並把視窗設定為1個位元組(但傳送的資料報為40位元組的的話)。接收,傳送方又發來1個位元組的資料(傳送方的IP資料報是41位元組)。接收方發回確認,仍然將視窗設定為1個位元組。這樣,網路的效率很低。要解決這個問題,可讓接收方等待一段時間,使得或者接收快取已有足夠空間容納一個最長的報文段,或者等到接收方快取已有一半空閒的空間。只要出現這兩種情況,接收方就發回確認報文,並向傳送方通知當前的視窗大小。此外,傳送方也不要傳送太小的報文段,而是把資料報積累成足夠大的報文段,或達到接收方快取的空間的一半大小。

2. 擁塞控制 擁塞控制是防止傳輸資料的聯絡層網路出擁塞時資料大量丟失的情況。 擁塞避免主要包含以下2個內容: (1)慢開始,擁塞避免 (2)快重傳,快恢復 2.1 慢開始和擁塞避免 2.1.1 慢開始原理 (1)在主機剛剛開始傳送報文段時可先將擁塞視窗 cwnd 設定為一個最大報文段 MSS 的數值。 (2)在每收到一個對新的報文段的確認後,將擁塞視窗增加至多一個 MSS 的數值。 (3)用這樣的方法逐步增大發送端的擁塞視窗 cwnd,可以使分組注入到網路的速率更加合理。 2.1.2 例項講解
注:圖中視窗的單位都是報文段 (1)當 TCP 連線進行初始化時: 傳送視窗:swnd = 1  慢開始閾值:ssthresh = 16 (2)傳送端收到 ACK1 (確認 M0,期望收到 M1)後,將 cwnd 從 1 增大到 2,於是傳送端可以接著傳送 M1 和 M2 兩個報文段(指數增長) (3)接收端發回 ACK2 和 ACK3。傳送端每收到一個對新報文段的確認 ACK,就把傳送端的擁塞視窗加 1。現在傳送端的 cwnd 從 2 增大到 4,並可傳送 M4 ~ M6共 4個報文段。(指數增長) (4)當swnd >= ssthresh,swnd執行擁塞避免演算法,swnd視窗按線性規律增長。 (加法增大) (5)當傳送 超時,此時swnd = 24 : ssthresh = swnd/2 = 12;(乘法減小) swnd = 1 (6)重複地2步。 2.2 快重傳和快恢復 2.2.1 快重傳 傳送端只要一連收到三個重複的 ACK 即可斷定有分組丟失了,就應立即重傳丟失的報文段而不必繼續等待為該報文段設定的重傳計時器的超時 2.2.2 快恢復 (1) 當傳送端收到連續三個重複的 ACK 時,就重新設定慢開始門限 ssthresh。 (2) 與慢開始不同之處是 swnd 不是設定為 1,而是設定為 ssthresh + 3 * MSS。  (3) 若收到的重複的 ACK 為 n 個(n > 3),則將 cwnd 設定為 ssthresh + n * MSS。 (4) 若傳送視窗值還容許傳送報文段,就按擁塞避免演算法繼續傳送報文段。 (5) 若收到了確認新的報文段的 ACK,就將 swnd 縮小到 ssthresh。