【圖解+漫話】什麼是確認重傳機制?兩天完全陌生的主機是如何辦到『數據的正確交付』的?




小白:你知道嗎?數據在傳輸的時候是分割成一小塊一小塊傳輸的,我們把這一小塊的數據稱之爲一個分組。我們在傳輸這塊分組的時候,主要面臨兩個問題。

1、這個分組在傳輸的過程中,由於在信道傳輸過程中,收到干擾,導致這個分組到達目的地之後出現了差錯,例如分組裏面的二進制位1變成了0,0變成了1。

2、分組還沒傳輸到目的地,就丟失了,我們也把這種情況稱之爲丟包。

接下來我們先來談談第一種情況吧,即分組傳到目的地之後出現了差錯。

這裏我們先假設計算機A給計算機B發送分組數據




在這裏插入圖片描述
一禪:如果沒有差錯的話,計算機B就給計算機A發送一個ACK分組,告訴對方,數據正確無誤。如果出現差錯的話,就給對方發送一個NAK分組,告訴對方,分組數據出現了差錯。

當計算機A收到接受方的反饋之後,如果收到的是ACK分組,那麼就繼續發送下一個分組數據。如果收到的是NAK分組,那麼就重新傳輸這個分組。



在這裏插入圖片描述
在這裏插入圖片描述
小白:這時就會出現了混亂,就相當於兩個人A,B在對話。

A : 傳輸給你一個分組

B :你發的是啥,可以重發一次嗎?

A :你發的又是啥?可以重發一次嗎?

B :你發的又是啥?可以重發一次嗎

進去無限混亂之中
在這裏插入圖片描述
在這裏插入圖片描述

小白:法子倒是不錯,不過如果分組出現大量差錯,會讓校驗碼變的很難設計的,而且校驗碼屬於與正文內容無關的數據,佔了太多比特位的話,會降低傳輸效率。還有其他法子嗎?




小白:我們可以給每個分組添加一個序號啊,這樣就可以知道是重傳的分組還是新的分組了。

如果B收到的分組沒出差錯,這時又收到一個序號相同的分組,這時B就知道這個分組是屬於重傳的分組了,這時B就把這個重傳的分組丟棄。
在這裏插入圖片描述

情況二:分組丟失時的問題處理

在這裏插入圖片描述
一禪:哈哈,我知道怎麼解決,可以採取和分組差錯類似的方法,如果A遲遲沒有收到B的反饋,A就可以認爲這個分組丟失了,重新發送。

所以我們每次發送分組的時候,需要給該分組設置一個定時器
在這裏插入圖片描述
小白:腦子轉的挺快啊。不過你知道嗎?我們上面談的那些,都是A發送一個分組,收到B的反饋之後,再發送下一個分組。你不覺得這種方法很浪費信道的資源嗎?




這裏先說明一下,如果同時發送多個分組時,最需要處理的問題就是接受方收到分組時,並非按照順序收到分組的,有可能序號小的分組先達到,這時就會出現了亂序。

回退N步協議(GBN)

在回退N步法中允許發送多個分組而不需要等待確認,但它也受限於在流水線中未確認的分組數不能超過某個最大允許數N。如下圖,我們將基序號定義爲最早的未確認分組的序號,將下一個序號(nextseqnum)定義爲最小的未使用序號(即下一個待發送分組)。

在這裏插入圖片描述
此時我們可以將序號分成4段。在[0, base-1]段內的序號對應已發送並且已經確認的分組序號,[base,nextseqnum]段內對應已經發送但未確認的分組序號,[nextseqnum, base+N-1]段內表示即將要被髮送的分組序號。而那些大於base+N的序號目前還不能使用,直到當前流水線中未被確認的分組得到確認,窗口整體向右移動之後,才能夠被使用。

所以,我們常把N稱之爲窗口長度,由於窗口在序號範圍內移動,也被GBN協議稱之爲滑動窗口協議

對於GBN協議,計算機A(發送方)需要響應以下兩個事件:
1、收到一個ACK:在GBN協議中,對序號爲n的分組的確認採取累計確認的方式。也就是說,當A收到序號爲n的分組時,表明分組n以及n之前的分組已經被B正確接受了。

2、超時事件: 當久久沒有收到ACK時,A就認爲它發送的分組已經丟失了,這時A會重傳所有已發送但還未被確認的分組。這個時候需要注意的是,並不是爲每個分組設置一個定時器,而是在序號[base,nextseqnum-1]中,設置一個定時器,當base發送的那一刻,就開始計時,當收到一個ACK時,則刷新重新開始計時。

計算機B(接收方)則需要處理一下事件:

如果一個序號爲n的分組被正確收到,並且按序(所謂按序就是指n-1的分組也已經收到了),則B爲分組n發送一個ACK,否則,丟棄該分組,並且爲最近按序接收的分組重新發送ACK。

接收方的這種處理方式,意味着如果n被正確交付,則意味着比n小的所有分組也被正確交付了。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

在這裏插入圖片描述

小白:你這個想法其實也是挺不錯的,不過如果分組n-1丟失了,那麼按照GBN的重傳規則,這時n-1和n都會被重傳,這時之前緩存的n就沒啥用了。而且,我們如果把n丟棄了,那麼我們就不需要緩存任何失序的分組了,這樣可以讓我們的設計更加簡單哦。

選擇重傳(SR)

回退N步協議的缺點也是很明顯的,單個分組的差錯能夠引起GBN重傳大量的分組,而且許多分組根本就沒有必要重傳。例如我們發送的序號爲0-100,萬一序號爲1的分組出現了某些差錯,這會導致1-100的分組會被重傳,想想這是多麼恐怖的事情啊。

因此,出現了選擇重傳這種協議。所謂“選擇”,也就是有選擇着去重傳。

不過選擇重傳和回退N步是很相似的,只是在選擇重傳中,接收方收到失序的分組時,會把它緩存起來,直到拼湊到分組按序,才把分組傳輸給上一層。而發送方會爲每個分組設置一個定時器,這樣,只需要重傳那些沒有被接收方正確接收的分組就可以了。

我來個例子吧。

假設窗口長度N=6,這時A向B發送分組1-5。
在這裏插入圖片描述
當A收到序號爲3的ACK,則狀態如下:
在這裏插入圖片描述
注意,這個時候雖然序號3被確認接收了,但窗口並不能向右移動一格。

接下來受到序號爲1的ACK,則:
在這裏插入圖片描述
這個時候窗口才可以向右移動一格。注意,黃色的那些序號是可以繼續發送分組的,只是我沒有繼續填充發送而已。

接着收到序號爲2的分組。
在這裏插入圖片描述
這個時候窗口向右移動了兩個格。

接着繼續這樣接收下去,如果還有分組沒發送的,就從nextseqnum開始填充發送…

如果某個分組超時了,就重新傳輸這個分組。

對於接收方B的窗口來說也差不多也一樣,在此不展開。接收方對於失序的分組緩存起來,直到所有丟失的分組全部被收到爲止,再把這批分組按序交付給上一層。

我在書上截了張完整的例子圖:

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

這樣,兩個完全陌生的計算機就可以就行可靠數據傳輸了。這也是可靠數據傳輸的原理。

在這裏插入圖片描述

最後一點感想

總感覺這篇文章講的好一般,感覺有點小囉嗦或者…也不知道怎麼說,本來我是想寫成那種一點一點引導出知識點的,不過在回退N步和選擇重傳中,有點不知道怎麼引導。不過我會爭取在後面的文章講的更加通俗易懂。

說實話,這篇文章其實算是比較簡單的幾個知識點,不過我還是寫了好久,加上自己畫圖之列的就更加了,哈哈。主要是一直不知道怎麼下手。不過就算花時間,我也會盡最大努力去寫。再次感謝讀者們的支持,在之後的文章裏,應該會數據結構與算法和計算機網絡穿插講。

擁塞控制以及流量控制其實也寫過的了,兩篇看這裏:
三分鐘基礎:什麼是流量控制?

三分鐘基礎:什麼是擁塞控制?

另外,我正在整理一份計算機類書單,只爲讓大家更加方便找到自己想要的書籍,目前已經收集了幾百本了,貢獻給需要的人計算機的書籍很貴?史上最全計算機類電子書整理(持續更新)

兄dei,如果覺得我寫的不錯,不妨幫個忙

1、關注我的原創微信公衆號「帥地玩編程」,每天準時推送乾貨技術文章,專注於寫算法 + 計算機基礎知識(計算機網絡+ 操作系統+數據庫+Linux),聽說關注了的不優秀也會變得優秀哦。

2、給俺點個讚唄,可以讓更多的人看到這篇文章,順便激勵下我,嘻嘻。

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