【網路協議】TCP的流量控制機制

蘭亭風雨發表於2014-06-20

    一般來說,我們總是希望資料傳輸的更快一些,但如果傳送方把資料傳送的很快,而接收方來不及接收,這就可能造成資料的丟失。流量控制就是讓傳送方的傳送速率不要太快,讓接收方來得及接收。

    對於成塊資料流,TCP利用滑動視窗機制來實現流量的控制,對於互動資料流,TCP利用捎帶ACK和Nagle演算法來實現流量的控制。

    後兩種就不說了,上篇博文中將已經寫得比較清楚了,對於滑動視窗機制,上篇博文中也又說到,只是沒有刻意提到用滑動視窗來實現流量的控制。下面就詳細說下利用滑動視窗機制來實現流量控制的機制,先看下圖:


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

    從圖中可以看出,B進行了三次流量控制。第一次把視窗減少到 rwnd = 300 ,第二次又減到了 rwnd = 100 ,最後減到 rwnd = 0 ,即不允許傳送方再傳送資料了。這種使傳送方暫停傳送的狀態將持續到主機B重新發出一個新的視窗值為止。

    我們考慮一種特殊情況,如果B在向A傳送了零視窗報文段後不久,B的接收快取又有了一些儲存空間,於是B向A傳送了一個rwnd=400的報文段,然而這個報文段在傳送過程中丟失了,A就一直等待B傳送非零視窗的報文通知,而B一直等待A傳送資料,如果沒有任何措施的話,這話死鎖的局面會一直延續下去。

    為了解決這個問題,TCP為每一個連線設有一個持續計時器(也叫堅持定時器)。只要TCP連線的一方收到對方的零視窗通知,就啟動持續計時器。若持續計時器設定的時間到期,就傳送一個零視窗控測報文段(攜1位元組的資料),對方在收到探測報文段後,在對該報文段的確認洪給出現在的視窗值,如果視窗值仍未零,則收到這個報文段的一方就重新設定持續計時器,如果視窗不為零,那麼死鎖的僵局就被打破了。

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

    

相關文章