1. 程式人生 > >計算機網路(七)--TCP的可靠傳輸原理及實現(一)

計算機網路(七)--TCP的可靠傳輸原理及實現(一)

可靠傳輸的工作原理

TCP傳送的報文段是交給IP層傳送的。但IP層只能提供盡最大努力服務。所以TCP必須採用適當的措施才能使兩個運輸層之間的通訊變得可靠。

理想的傳輸條件:

(1)傳輸通道不產生差錯。

(2)不管傳送方以多快的速度傳送資料,接收方總是來得及處理收到的資料。

措施:當出現差錯時讓傳送方重傳出現差錯的資料,同時在接收方來不及處理收到的資料時,及時告訴傳送方適當降低傳送資料的速度。由此用不可靠的傳輸通道實現可靠傳輸。

最簡單的協議:停止等待協議

“停止等待”就是每傳送完一個分組就停止傳送,等待對方的確認。在收到確認後再發送下一個分組。(因為討論可靠傳輸的原理,因此把傳送的資料單元都稱為分組)

全雙工通訊的雙方既是傳送方也是接收方。僅考慮A傳送資料而B接收資料併發送確認。稱為A叫做傳送方,而B叫做接收方。

可靠傳輸協議的設計:A只要超過了一段時間仍然沒用收到確認,就認為剛才傳送的分組丟失了,因而重傳前面傳送過的分組。這就叫做超時重傳

超時重傳的實現:在每傳送完一個分組設定一個超時計時器。如果在超時計時器到期之前收到了對方的確認,就撤銷已設定的超時計時器

注意三點:

第一,A在傳送完一個分組後,必須暫時保留已傳送的分組的副本(為發生超時重傳時使用)。只有在收到相對應的確認後才能清除暫時保留的分組副本。

第二,分組和確認分組都必須進行編號。這樣才能明確是哪一個傳送出去的分組收到了確認,而哪一個分組還沒有收到確認。

第三,超時計時器設定的重傳時間應當比資料在分組傳輸的平均往返時間更長一些

A在設定的超時重傳時間內沒有收到確認,情況有兩種:

1)A傳送的分組出錯、丟失。

2)B傳送的確認丟失了。

超時重傳的情況有兩種:

無論上述哪種情況,B收到重傳的分組後,向A傳送確認。若分組重複就丟棄,否則上交。(即B每次收到分組檢測無誤後,就向A傳送確認,無論該分組是否重複。但重複的分組會被丟棄)

若B傳送的確認遲到了(無論它是否在重傳後收到B傳送的第二份確認),A會收下重複的確認後丟棄。

像上述的這種可靠傳輸協議常稱為自動重傳請求ARQ(Automatic Repeat reQuest)。意思是重傳的請求是自動進行的。接收方不需要請求傳送方重傳某個出錯的分組。


停止等待協議的優點時簡單,缺點是通道利用率太低。

為了提高傳輸效率,傳送方採用流水線傳輸。當使用流水線傳輸時,就要使用下面介紹的連續ARQ協議滑動視窗協議


通道利用率: U = TD /(TD +RTT+TA)

TD為A傳送分組需要的時間,其值為分組長度除以資料率。RTT是往返時間,其取決於所使用的通道。TA是B傳送確認分組需要的時間。

若出現重傳,則對傳送有用的資料資訊來說,通道的利用率就還要降低。

連續ARQ協議

傳送視窗:位於傳送視窗內的分組都可以連續傳送出去,而不需要等待對方的確認。

分組傳送是按照分組序號從小到大發送的。

連續ARQ協議規定,傳送方每收到一個確認,就把傳送視窗向前滑動一個分組的位置。

接收方一般都是採用累積確認的方式。接收方不必對收到的分組逐個傳送確認,而是在收到幾個分組後,對按序到達的最後一個分組傳送確認,表示到這個分組為止的所有分組都已正確收到了。

缺點:不能向傳送方反映出接收方已經正確收到的所有分組的資訊。

TCP可靠傳輸的實現

為了講述的方便,假定資料傳輸只在一個方向進行,即A傳送資料,B給出確認。

TCP的滑動視窗是以位元組為單位的。

A的傳送視窗由收到的確認報文段中的視窗值確認號來構建傳送視窗。

傳送視窗表示:在沒有收到B的確認的情況下,A可以連續把視窗內的資料都發送出去。凡是已經發送過的資料,在未收到確認之前都必須暫時保留,以便在超時重傳時使用。

傳送視窗的位置由視窗前沿和後沿的位置共同確定。後沿後面部分是已傳送並收到確認,前沿前面部分是不允許傳送的,因為接收方沒有為這部分資料保留快取。

傳送視窗前沿通常是不斷向前移動,也有可能不動(每收到新的確認,或收到新的確認但對方通知的視窗縮小了)。

傳送視窗前沿也有可能向後收縮。但TCP的標準強烈不贊成這樣做。因為很可能傳送方在收到這個通知以前已經發送了視窗中的許多資料,現在又要收縮視窗,不讓傳送這些資料,這樣就會產生一些錯誤。

由上述可見,描述一個傳送視窗的狀態需要三個指標:p1,p2,p3。

小於p1的是已傳送並已收到確認的部分,而大於p3的是不允許傳送的部分。大於等於p1到小於p2的是已傳送但未收到確認,大於等於p2到小於p3的是允許傳送但尚未傳送。

接收方B只能對按序收到的資料中的最高序號給出確認。

傳送方A在沒有收到確認報文期間會做什麼?,傳送方會持續傳送傳送視窗的資料。若沒有資料可以傳送了,一定時間後仍未收到確認(超時),則重傳這部分資料。(?不確定是第一個資料傳送時會進行計時,還是沒有資料傳送時開始計時)

接收方B什麼時候會給A傳送確認?接收方B將收到的一部分按序的資料上交主機後,刪除這些資料,移動接收視窗,然後給A傳送確認。

傳送方的應用程序把位元組流寫入TCP的傳送快取,接收方的應用程序從TCP的接收快取中讀取位元組流。

第一,快取空間和序號空間都是有限的,並且都是迴圈使用的。這裡為了畫圖的方便,把它們畫成長條狀,同時不考慮迴圈使用快取空間和序號空間的問題。

第二,由於實際上快取或視窗中的位元組數是非常之大的,無法在圖中把一個個位元組的位置標註清楚。


傳送快取用來暫時存放:

1)傳送應用程式傳送給傳送方TCP準備傳送的資料。

2)TCP已傳送出但尚未收到確認的資料。

傳送視窗通常只是傳送快取的一部分,已經確認的資料應當從傳送快取中刪除,因此,傳送快取和傳送視窗的後沿是重合的。

接收快取用來暫時存放:

1)按序到達的、但尚未被接收應用程式讀取的資料。

2)未按序到達的資料。

根據以上所得,強調三點:

第一,雖然A的傳送視窗是根據B的接收視窗設定的,但在同一時刻,A的傳送視窗並不總是和B的接收視窗一樣大。這是因為通過網路傳送視窗值需要經歷一定的時間滯後(這個時間還是不確定的)。另外,傳送方A還可能根據網路當時的擁塞情況適當減小自己的傳送視窗數值。

第二,對於不按序到達的資料應如何處理,TCP標準並無明確規定。如果接收方把不按序到達的資料一律丟棄,那麼接收視窗的管理將會比較簡單,但這樣做對網路資源的利用不利(因為傳送方會重複傳送較多地資料)。因此TCP通常對不按序到達的資料是先臨時存放在接收視窗中,等到位元組流中所缺少的位元組收到後,再按序交付上層的應用程序。

第三,TCP要求接收方必須有累積確認的功能,這樣可以減小傳輸開銷。接收方可以在合適的時候傳送確認,也可以在自己有資料要傳送時把確認資訊順便捎帶上。但請注意兩點,一是接收方不應過分推遲傳送確認,否則會導致傳送方不必要的重傳,這反而浪費了網路的資源。TCP標準規定,確認推遲的時間不應超過0.5秒。若收到一連串具有最大長度的報文段,則必須每隔一個報文段就要傳送一個確認。二是捎帶確認實際上並不經常發生,因為大多數應用程式不同時在兩個方向上傳送資料。

超時重傳時間的選擇

TCP的傳送方在規定的時間內沒有收到確認就要重傳已傳送的報文段。這種重傳的概念是很簡單的,但重傳時間的選擇卻是TCP最複雜的問題之一。

原因:TCP的下層是網際網路環境,傳送的報文段可能只經過一個高速率的區域網,也可能經過多個低速率的網路,並且每個IP資料報所選擇的路由還可能不同。如果把超時重傳時間設定得太短,就會引起很多報文段的不必要的重傳,使網路負荷增大。但若把超時重傳時間設定得過長,則又使網路的空閒時間增大,降低了傳輸效率。

TCP採用了一種自適應演算法,它記錄一個報文段發出的時間,以及收到相應的確認的時間。這兩個時間之差就是報文段的往返時間RTT。TCP保留了RTT的一個加權平均往返時間RTTs(這又稱為平滑的往返時間,S表示Smoothed。因為進行的是加權平均,因此得出的結果更加平滑)。

每當第一次測量到RTT樣本時,RTTs值就取為所測量到的RTT樣本值。但以後每測量到一個新的RTT樣本,就按下式重新計算一次RTTs:

新的RTTs = (1-a)* (舊的RTTs) + a * (新的RTT樣本)

若a接近零,表示新的RTTs值和舊的RTTs值相比變化不大。若a接近1,表示RTT值更新較快。RFC2988推薦的a值為1/8,即0.125。

超時重傳時間RTO(Retransmission Time-out)應略大於加權平均往返時間RTTs。RFC2988建議使用下式計算RTO:

RTO = RTTs + 4 *RTTD                     RTTD  是RTT的偏差的加權平均值,它與RTTs和新的RTT樣本之差有關。

新的RTTD = (1-p)*(舊的RTTD) +  p * | RTTs -   新的RTT樣本|              p是個小於1的係數,推薦值是1/4,即0.25。

傳送出一個報文段。設定的重傳時間到了,還沒有收到確認。於是重傳報文段。經過了一段時間後,收到了確認報文段。

問題:如何判定此確認報文段是對先發送的報文段的確認,還是對後來重傳的報文段的確認?

答:由於重傳的報文段和原來的報文段完全一樣,無法做出正確的判斷,而正確的判斷對確定加權平均RTTs的值關係很大。

解答:karn提出了一個演算法,在計算加權平均RTTs時,只要報文段重傳了,就不採用其往返時間樣本。這樣得出的加權平均RTTs和RTO就較準確

新問題:報文段的時延突然增大很多。因此在原來得出的重傳時間內,不會收到確認報文段。於是就重傳報文段。但根據Karn演算法,不考慮重傳的報文段的往返時間樣本。這樣,超時重傳時間就無法更新。

解答:對Karn演算法修正,報文段每重傳一次,就把超時重傳時間RTO增大一些。典型的做法是取新的重傳時間為2倍的舊的重傳時間。當不再發生報文段的重傳時,才根據上面給出的公式計算超時重傳時間。

Karn演算法能夠使運輸層區分開有效的和無效的往返時間樣本,從而改進了往返時間的估測。

選擇確認SACK

若收到的報文段無差錯,只是未按序號,中間還缺少一些序號的資料,那麼能否設法只傳送缺少的資料而不重傳已經正確到達接收方的資料?選擇確認就是一種可行的處理方法。

如果要使用選擇確認SACK,那麼在建立TCP連線時,就要在TCP首部的選項中加上“允許SACK”的選項,而雙方必須都事先商定好。

由於首部選項的長度最多隻有40位元組,在選項中最多隻能指明4個位元組塊的邊界資訊(4*2*4,序號有32位,一個邊界需要4位元組)。

另外需要兩個位元組,一個位元組指明是SACK選項,另一個位元組指明這個選項佔用多少位元組。

SACK文件並沒有指明發送方應當怎樣響應SACK。因此大多數的實現還是重傳所有未被確認的資料塊。

相關推薦

計算機網路--TCP可靠傳輸原理實現

可靠傳輸的工作原理 TCP傳送的報文段是交給IP層傳送的。但IP層只能提供盡最大努力服務。所以TCP必須採用適當的措施才能使兩個運輸層之間的通訊變得可靠。 理想的傳輸條件: (1)傳輸通道不產生差錯。 (2)不管傳送方以多快的速度傳送資料,接收方總是來得及處理收到的資料。

深入淺出圖解【計算機網路】 之 【TCP可靠傳輸實現: 三次握手+滑動視窗】

【前言】這個系列主要會介紹一些計算機網路體系中“看上去稍有些複雜”但“一旦理解了又會很容易”的內容,我會嘗試通過示意圖/動圖的方式對概念進行儘量直觀的詮釋,如果能夠對大家學習計算機網路有所啟發的話就最好了。 TCP(Transmission Control Protocol)是整個TCP/IP協議

網絡學習筆記TCP可靠傳輸原理

不必要 不一定 網絡學習 建立 位置 arq協議 四種 數據碎片 cnblogs ??TCP數據段作為IP數據報的數據部分來傳輸的,IP層提供盡最大努力服務,卻不保證數據可靠傳輸。TCP想要提供可靠傳輸,需要采取一定的措施來讓不可靠的傳輸信道提供可靠傳輸服務。比如:出現差錯

Socket通用TCP通訊協議設計實現防止粘包,可移植,可靠

Socket通用TCP通訊協議設計及實現(防止粘包,可移植,可靠) 引文 我們接收Socket位元組流資料一般都會定義一個數據包協議。我們每次開發一個軟體的通訊模組時,儘管具體的資料內容是不盡相同的,但是大體上的框架,以及常用的一些函式比如轉碼,校驗等等都是相似甚至一樣的

智能指針原理實現1- shared_ptr

red ++ 直接 初始 targe -- div urn 記錄 C++沒有內存回收機制,每次程序員new出來的對象需要手動delete,流程復雜時可能會漏掉delete,導致內存泄漏。於是C++引入智能指針,可用於動態資源管理,資源即對象的管理策略。 一、智能指針類別 智

智能指針原理實現2- unique_ptr

unique clas 結束 基礎 無法 body 智能指針 周期 文件 只允許基礎指針的一個所有者。 可以移到新所有者(具有移動語義),但不會復制或共享(即我們無法得到指向同一個對象的兩個unique_ptr)。 替換已棄用的 auto_ptr。 相較於 boost::s

Vue 進階系列之Render函式原理實現

Vue進階系列彙總如下,歡迎閱讀,歡迎加高階前端進階群一起學習(文末)。 Vue 進階系列(一)之響應式原理及實現 Vue 進階系列(二)之外掛原理及實現 Render函式原理 根據第一篇文章介紹的響應式原理,如下圖所示。 在初始化階段,本質上發生在auto run函式中,然後通過r

字串匹配原理實現C++版

字串匹配原理及實現(C++版) 1. 字串匹配概念 2. BF 2.1 原理 2.2 程式碼實現 3. KMP 3.1 原理 3.2 程式碼實現 4. BM 4.1 壞字元

Command Pattern -- 命令模式原理實現C++

主要參考《大話設計模式》和《設計模式:可複用面向物件軟體的基礎》兩本書。本文介紹命令模式的實現。            What it is:Encapsulate a request as an object, thereby letting you parameterize clients with di

順序表的插入操作原理實現C語言詳解

順序表中存放資料的特點和陣列這種資料型別完全吻合,所以順序表的實現使用的是陣列。換句話說,順序表中插入元素問題也就等同於討論如何向陣列中插入資料。 因此,順序表中插入資料元素,無非三種情況: 在表頭插入; 在表的中間某個位置插入; 直接尾隨順序表,作為表的最後一個元素; 無論在順序表的什麼位置插

氣泡排序演算法原理實現超詳細

氣泡排序(Bubble Sort)是排序演算法裡面比較簡單的一個排序。它重複地走訪要排序的數列,一次比較兩個資料元素,如果順序不對則進行交換,並一直重複這樣的走訪操作,直到沒有要交換的資料元素為止。 氣泡排序的原理 為了更深入地理解氣泡排序的操作步驟,我們現在看一下氣泡排序的原理。 首先我們肯定有一個數組

HTTP 代理原理實現

文章目錄 普通代理 隧道代理 提醒:本文最後更新於 1097 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 Web 代理是一種存在於網路中間的實體,提供各式各樣的功能。現代網路系統中,Web 代理無處不在。我之前有關 HTTP 的博文中,多次提到了代理對 HTTP 請

HTTP 代理原理實現

提醒:本文最後更新於 1096 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 在上篇《HTTP 代理原理及實現(一)》裡,我介紹了 HTTP 代理的兩種形式,並用 Node.js 實現了一個可用的普通 / 隧道代理。普通代理可以用來承載 HTTP 流量;隧道代理可以用來承載任何 TCP 流量,

快速排序演算法原理實現單軸快速排序、三向切分快速排序、雙軸快速排序

歡迎探討,如有錯誤敬請指正 1. 單軸快速排序的基本原理 快速排序的基本思想就是從一個數組中任意挑選一個元素(通常來說會選擇最左邊的元素)作為中軸元素,將剩下的元素以中軸元素作為比較的標準,將小於等於中軸元素的放到中軸元素的左邊,將大於中軸元素的放到中軸元素的右邊,然後以當前中軸元素的位置為界,將左半部分子

AVL樹原理實現C語言實現以及Java語言實現

歡迎探討,如有錯誤敬請指正 如需轉載,請註明出處http://www.cnblogs.com/nullzx/ 1. AVL定義 AVL樹是一種改進版的搜尋二叉樹。對於一般的搜尋二叉樹而言,如果資料恰好是按照從小到大的順序或者從大到小的順序插入的,那麼搜尋二叉樹就對退化成連結串列,這個時候查詢,插入和刪除的

眼底影象血管增強與分割--2Gabor濾波演算法原理實現

Gabor濾波演算法 維基裡給出的解釋,“In image processing, aGabor filter is a linear filter used fortextureanalysis,

寫程式學ML:Logistic迴歸演算法原理實現

2.2   利用Logistic演算法預測病馬死亡率 由於採集資料是諸多原因,採集的資料有可能不完整。但有時候資料相當昂貴,扔掉和重新獲取都是不可取的,所以必須採用一些方法來解決這個問題。 處理資料中缺失值的做法: 1>    使用可用特徵的均值來填補缺失值; 2&g

寫程式學ML:樸素貝葉斯演算法原理實現

[題外話]近期申請了一個微信公眾號:平凡程式人生。有興趣的朋友可以關注,那裡將會涉及更多更新機器學習、OpenCL+OpenCV以及影象處理方面的文章。 1、樸素貝葉斯演算法的原理 樸素貝葉斯法是基於貝葉斯定理與特徵條件獨立假設的分類方法。 和決策樹模型相比,樸素貝葉斯

寫程式學ML:Logistic迴歸演算法原理實現

[題外話]近期申請了一個微信公眾號:平凡程式人生。有興趣的朋友可以關注,那裡將會涉及更多更新機器學習、OpenCL+OpenCV以及影象處理方面的文章。 1、Logistic迴歸演算法的原理 假設現在有一些資料點,我們用一條直線對這些點進行擬合(該線稱為最佳擬合直線),這個

寫程式學ML:樸素貝葉斯演算法原理實現

[題外話]近期申請了一個微信公眾號:平凡程式人生。有興趣的朋友可以關注,那裡將會涉及更多更新機器學習、OpenCL+OpenCV以及影象處理方面的文章。 2、樸素貝葉斯演算法的實現 2.1   樸素貝葉斯演算法的實現 按照樸素貝葉斯演算法的原理,我們需要實現一個樸素貝葉