构造可靠数据传输协议
在本篇文章中我們將逐步了解開發發送方和接收方的可靠數據傳輸協議的過程,它們逐漸復雜,最后會得到一個無錯、可靠的數據傳輸協議。在這個過程中僅考慮單向數據傳輸但控制信息雙向流動。
我們用有限狀態機(FSM)來標識發送方和接收方。如下圖所示:
實線箭頭指示了協議從一個狀態變遷到另一個狀態。在對應的一個箭頭上,有個類似分數樣子的數據。橫線上方表示導致狀態轉換的事件,橫線下方是狀態轉換時執行的動作。接下來本文所有的圖都按此理解。
一、Rdt1.0:完全可靠信道上的可靠數據傳輸
首先考慮最簡單的情況,即在完全可靠的信道上,沒有bit錯誤、沒有分組丟失。
這時發送方與接收方的有限狀態機定義如下圖:
其中,發送方發送數據到下層信道,接收方從下層信道接收數據。發送方和接收方有各自的FSM,并且都只有一個狀態,都是從一個狀態返回到自身。
發送端通過rdt_send(data)事件接收來自較高層的數據,經過make_pkt(data)事件把上層的數據轉換成下層可以識別的數據段,然后把data數據通過udt_send(packet)發到下層IP層。
接收方通過rdt_rcv(paclet)函數從IP層接收數據,收到信息包之后繼續等待來自下層的調用,這個過程的事件主要是將數據段轉換成數據,交給應用層。
對于rdt1.0總結一句話就是假設信道沒有出錯,只是做兩個動作,一個是交付,一個是上傳。
二、Rdt2.0:具有bit錯誤的信道
1、確認和否認機制
假設rdt2.0具有bit錯誤的信道,因為這個過程下層信道可能讓傳輸分組中的bit受損。校驗和將檢測到bit錯誤。
那么當檢測到錯誤以后如何從錯誤中恢復呢?這里我們采用了確認和否認的機制。
(1)確認(ACK):接收方明確告訴發送方,分組接收正確。
(2)否認(NAK):接收方明確告訴發送方,分組接收出錯。
發送方在收到NAK后重發這個分組。
2、rdt新機制
在rdt2.0的新機制,即在rdt1.0中沒有的主要有如下:
(1)差錯檢測:接收方檢測到何時出現了比特差錯。需要有額外的比特,這些比特被匯集在rdt2.0數據分組的分組檢驗和字段中。
(2)接收方反饋:接收方提供明確的反饋信息給發送方,如ACK和NAK。
(3)接收方收到有差錯的分組時,發送方將重傳該分組報文。
3、rdt2.0FSM規范
注意:如果對一個事件沒有動作,或沒有就事件發送而采取了一個動作,將在橫線上方或下方使用符號A表示。
在這個過程中發送方首先等待來自上層的調用,做兩個事情,第一個是rdt_send(data)接收上層數據。snkpkt與1.0相比加了一個校驗和,可以檢測到是否發送錯誤,之后udp_send(snkpkt)將分組發送出去。之后發送方等待來自接收方的ACK或NAK分組。如果收到一個ACK分組,則發送方知道最近發送的分組已經被正確接收,此時協議返回到等待來自上層調用的狀態;如果收到一個NAK分組,則該協議會重傳最后一個分組并等待接收方為響應重傳分組而回送的ACK或NAK分組。
rdt2.0中接收方的FSM同樣只有一個狀態,當分組到達時,接收方根據接收到的分組是否受損要么回答一個ACK,要么回答一個NAK。
(1)當沒有錯誤時整個發送方與接收方操作如圖所示:
(2)當出現錯誤場景時發送方與接收方的操作如下圖所示:
rdt2.0錯誤場景其實就是一個停等協議,什么是停等協議呢?就是發送方發送一個報文,然后等到接收方的響應,響應類型有ACK和NAK兩種,如果是ACK則為正常數據交付,如果是NAK要進行重傳。
處理受損ACK和NAK時會發生如下三種情況:
(1)發送方并不知道接收方發生了什么。例如當我們說話時接收方回答的"請重復一遍",發送方會問“你說什么?”。
(2)增加足夠的檢驗和比特,使發送方不僅可以差錯檢測,還可以回復差錯。對于會產生差錯但不丟失分組的信道,這就可以直接解決問題。
(3)發送方收到含糊不清的ACK或NAK分組。
4、rdt2.0致命缺陷
我們考慮當ACK/NAK混淆了會發生什么?這時就會發生上面提到的發送方并不知道接收方發生了什么,使得不能正確重發數據,可能會導致數據重復。
解決方法:發送方給每個分組加一個序號,在ACK/NAK混淆時發送方重發當前分組,之后接收方會丟棄重復的分組但并不向上傳遞。
三、Rdt2.1:處理混亂的ACK/NAK
1、發送方處理混亂的ACK/NAK
FSM描述如下圖:
發送方的FSM是rdt2.0的兩倍,這是因為協議狀態此時必須反映出目前由發送方正發送的分組或者接收方希望接收的分組的序號是0還是1。在這個過程中發送方首先等待來自上層的調用,通過rdt_send(data)接收上層數據。snkpkt與2.0相比加了一個分組序號,用以標識所發送的分組,之后udp_send(snkpkt)將分組0發送出去。然后發送方等待來自接收方的ACK或NAK回送。如果收到一個ACK分組,則發送方知道最近發送的分組已經被正確接收,此時發送方的分組序號變為1,協議返回到等待來自上層調用的狀態;如果收到一個NAK分組,則該協議會重傳最后一個分組并等待接收方為響應重傳分組而回送的ACK或NAK分組,當接收方收到序號為0的分組時就會知道這是一次重傳。
2、接收方處理混亂的ACK/NAK
FSM描述如下圖:
接收方首先等待來自下層的調用,現在它希望收到的是一個分組0,當發送方傳過來的數據有誤時會回送NAK,然后等待發送方發來分組0。當確認數據無誤后會將數據傳遞給上層。此時接收方會期望接收到分組1。
四、Rdt2.2:一個不要NAK的協議
如果不發送NAK,而是對上次正確接收的分組發送一個ACK,我們也能實現與NAK一樣的效果。發送方接收到對同一個分組的兩個ACK,就知道接收方沒有正確接收到跟在被確認兩次的分組后面的分組。通俗的來說就是假如發送方先發送分組0,之后發送分組1,這是接收方如果返回來的還是分組0的ACK,發送方接收到兩個分組0的ACK,就知道分組1沒有被接收方接收到。
rdt2.2同rdt2.1相比功能相同,但是只用ACK不用NAK,接收方此時必須包括一個ACK報文所確認的分組序號,而發送方也必須檢查接收到的ACK報文中被確認的分組序號。
發送方、接收方FSM片段如圖:
五、Rdt3.0:具有出錯和丟失的信道
1、rdt3.0介紹
我們假設下層信道還要丟失報文、數據或者是ACK,校驗和、序號、確認、重傳雖然有一定的幫助,但是遠遠不夠。
我們采用如下方法:發送者等待“合理的”確認時間。如果在這時間內沒有收到ACK就重發該分組。但是如果一個分組經歷了特別大的時延,即數據或ACK只是延遲但并沒有丟失,發送方也會重傳該分組,這就在發送方帶接收方的信道中引入了冗余數據分組的可能性。幸運的是rdt2.2中的序號處理已經處理了這個問題。
從發送者的角度來看,重傳就好像是”萬靈藥“一樣。發送方并不知道是一個數據分組丟失,還是回送的ACK丟失,還是數據或ACK只是延遲但并沒有丟失。以上所有的情況,發送方的動作都是重傳。為了實現基于時間的重傳機制,需要一個倒計數定時器。倒計數定時器的作用為在一個給定的時間量過期后可以中斷發送方。
基于上,發送方要有如下功能:
(1)每次發送一個分組(包括第一次分組和重傳分組)時就會啟動一個定時器。
(2)采取適當動作響應定時器中斷。
(3)終止定時器。
注意:等待的”合理的“時間至少是發送方與接收方之間的一個往返時延加上接收方處理一個分組所需要的時間。
下圖為發送方的FSM:
2、rdt3.0操作
基于上圖rdt3.0有四種情況,我們用圖分別來講。
(1)無丟包操作
這種情況很好理解,發送方發送分組0,接收方接收0分組并回送ACK0,發送方收到ACK0之后發送分組1,以此類推。
(2)分組丟失
發送方發送分組0,接收方接收0分組并回送ACK0,發送方收到ACK0之后發送分組1,在發送分組1的過程中分組1丟失,發送方等待接收方的回送,等待超時后定時器中斷發送方重發分組1,j接收方接收分組1,回送ACK1。
(3)丟失ACK
發送方發送分組0,接收方接受分組0回送ACK0,發送方收到ACK0的回送后發送分組1,接收方接收分組1,但是在回送ACK1時發生丟失,當發送方等待超時后重發分組1,接收方接收分組1,檢測冗余,之后回送ACK1。
(4)過早超時
發送方發送分組0,接收方接收分組0并回送ACK0,之后發送方接收ACK0發送分組1,接受方接收分組1并回送ACK1A(為了區別下面的ACK1我們后面分別加個A和B),這時因為過早超時,還沒有等到ACK1回送過去就中斷定時器重傳分組1,接收方收到分組1后進行冗余檢測在回送ACK1B,在這同時發送方接收到了最開始接收方回送的ACK1A,然后發送分組0。之后發送方就什么也不做了。
3、rdt3.0性能
rdt3.0能工作但是性能很差,網絡協議限制了物質資源的使用!
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的构造可靠数据传输协议的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux学习:文件描述符表
- 下一篇: TCP概述