(二十三)運輸層--TCP可靠傳輸的實現

TCP可靠傳輸的實現

這篇文章我們來學習TCP可靠傳輸的實現。

爲了方便討論,我們假定數據傳輸只在一個方向進行,即A發送數據,B給出確認。這樣的好處是使討論限於兩個窗口,即發送方A的發送窗口和接收方B的接收窗口。

以字節爲單位的滑動窗口

TCP的滑動窗口是以字節爲單位的。現假定A收到了B發來的確認報文段,其中窗口是10字節(B的接收窗口是10字節),而確認號是28(表明B期望收到的下一個序號是28,而序號28爲止的數據已收到了)。根據這兩個數據,A就構造出自己的發送窗口,如下圖所示:

先討論發送方A的發送窗口。發送窗口表示:在沒有收到B的確認的情況下,A可以連續把窗口內的數據都發送出去。凡是已經發送過的數據,在未收到確認之前都必須暫時保留,以便在超時重傳時使用。發送窗口裏面的序號表示允許發送的序號。顯然,窗口越大,發送方就可以在收到對方確認之前連續發送更多的數據,因而可能獲得更高的傳輸效率。A的發送窗口一定不能超過B的接收窗口數值(發送方的發送窗口大小還要受到當時網絡擁塞程度的制約,但目前,暫不考慮)。

發送窗口後沿的後面部分表示已發送且已收到了確認,這些數據顯然不需要再保留了。發送窗口前沿的前面部分表示不允許發送的,因爲接收方都沒有爲這部分數據保留臨時存放的緩存空間。

發送窗口的位置由窗口前沿和後沿的位置共同確定。發送窗口後沿的變化情況有兩種可能,即不動(沒有收到新的確認)和前移(收到了新的確認)。發送窗口後沿不可能向後移動,因爲不能撤銷掉已收到的確認。發送窗口前沿通常是不斷向前移動,但也有可能不動(兩種情況,一是沒有收到新的確認,發送窗口的大小不變;二是收到了新的確認但對方通知的窗口縮小了,使得發送窗口前沿正好不動)。

現在假定A發送了序號爲28~34的數據。這時,發送窗口位置並未改變,但發送窗口內靠後面有7個字節表示已發送但未收到確認。而發送窗口內靠前面的3個字節是允許發送但尚未發送的。

要描述一個發送窗口的狀態需要三個指針:P1, P2, P3。指針都指向字節的序號,意義如下:
(1)小於P1的是已發送並已收到確認的部分,大於P3的是不允許發送的
(2)P3 - P1爲A的發送窗口
(3)P2 - P1爲已發送但尚未收到確認的字節數
(4)P3 - P2爲允許發送但當前尚未發送的字節數(又稱爲可用窗口或有效窗口)

再看一下B的接收窗口。B的接收窗口大小是10。在接收窗口外面,到28號爲止的數據是已經發送過確認,並且已經交付主機了。因此B可以不再保留這些數據。接收窗口內的序號(28~37)是允許接收的。在下圖中,B收到了序號爲29和30的數據。這些數據沒有按序到達,因爲序號爲28的數據沒有收到(也許丟失了,也許滯留在網絡中的某處)。請注意,B只能對按序收到的數據中的最高序號給出確認,因此B發送的確認報文段中的確認號仍然是28,而不是29或30。

現在假定B收到了序號爲28的數據,並把序號爲28~30的數據交付主機,然後B刪除這些數據,接着把接收窗口向前移動3個序號,同時給A發送確認,其中窗口值仍爲10,但確認號是31。這表明B已經收到了序號31爲止的數據。此時B還收到了序號爲32, 33的數據,但這些都沒有按序到達,只能先暫存在接收窗口中。A收到B的確認後,就可以把發送窗口向前滑動3個序號,但指針P2不動。可以看出,現在A的可用窗口增大了,可發送的序號範圍是35~40。

如下圖所示,A在繼續發送完序號35~40的數據後,指針P2向前移動和P3重合。發送窗口內的序號都已用完,但還沒有收到確認。由於A的可用窗口減小到0,因此必須停止發送。A在經過一段時間後(由超時計時器控制),就重傳這部分數據,重新設置計時器,直到收到B的確認爲止。如果A收到確認號落在發送窗口內,那麼A就可以使發送窗口繼續向前滑動,併發送新的數據。請注意,在沒有收到B的確認時,爲了保證可靠傳輸,A只能認爲B還沒有收到這些數據。

前文說過,發送方的應用進程把字節流寫入TCP的發送緩存,接收方的應用進程從TCP的接收緩存中讀取字節流。下面進一步討論窗口和緩存的關係。

如下圖所示,畫出了發送方維持的發送緩存和發送窗口:

發送緩存用來暫時存放:
(1)發送應用程序傳送給發送方TCP準備發送的數據
(2)TCP已發送但尚未收到確認的數據
發送窗口通常只是發送緩存的一部分。已被確認的數據應當從發送緩存中刪除,因此發送緩存和發送窗口的後沿是重合的。發送應用程序最後寫入發送緩存的字節減去最後被確認的字節,就是還保留在發送緩存中的被寫入的字節數。發送應用程序必須控制寫入緩存的速率,不能太快,否則發送緩存就會沒有存放數據的空間。

如下圖所示,畫出了接收方維持的接收緩存和接收窗口:

接收緩存用來暫時存放:
(1)按序到達的,但尚未被接收應用程序讀取的數據
(2)未按序到達的數據
如果收到的分組被檢測出有差錯,則要丟棄。如果接收應用程序來不及讀取收到的數據,接收緩存最終就會被填滿,使接收窗口減小到0。反之,如果接收應用程序能夠及時從接收緩存中讀取收到的數據,接收窗口就可以增大,但最大不能超過接收緩存的大小。

根據以上的討論,強調以下三點:
(1)雖然A的發送窗口是根據B的接收窗口設置的,但在同一時刻,A的發送窗口並不總是和B的接收窗口一樣大。這是因爲通過網絡傳送窗口值需要經歷一定的時間滯後,發送方A還可能根據網絡當時的擁塞情況適當減小自己的發送窗口數值

(2)對於不按序到達的數據應如何處理,TCP標準並無明確規定。如果接收方把不按序到達的數據一律丟棄,那麼接收窗口的管理將會比較簡單,但這樣做對網絡資源的利用不利,因爲發送方會重複傳送較多的數據。因此TCP通常對不按序到達的數據是先臨時存放在接收窗口中,等到字節流中所缺少的字節收到後,再按序交付上層的應用進程。
(3)TCP要求接收方必須有累計確認的功能,這樣可以減小傳輸開銷。接收方可以在合適的時候發送確認,也可以在自己有數據要發送時把確認信息順便捎帶上。但注意兩點,一是接收方不應過分推遲發送確認,否則會導致發送方不必要的重傳,這反而浪費了網絡的資源。TCP標準規定,確認推遲的時間不應超過0.5秒。若收到一連串具有最大長度的報文段,則必須每隔一個報文段就發送一個確認。二是捎帶確認實際上並不經常發生,因爲大多數應用程序很少同時在兩個方向上發送數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章