rdt2.x協(xié)議提供了在只有比特錯誤的信道上的可靠傳輸服務(wù)。
書中提供了幾個很巧妙的有限狀態(tài)機,但是關(guān)于這幾個有限狀態(tài)機的設(shè)計邏輯卻提及較少,所以本文先進行一些書中基礎(chǔ)概念的引入,進行梳理,然后對關(guān)于rdt2.x協(xié)議的設(shè)計邏輯進行詳細描述。
基本概念:
比特錯誤:分組中的可能會由0變?yōu)?,或由1變?yōu)?。
冗余分組:一個已經(jīng)接收的分組再次到達。
序號:為分組編號,通過在分組中添加一個序號字段來實現(xiàn)。在rdt2.x中的目的是為了檢測冗余分組,并且只用了[0,1]范圍內(nèi)的序號。
肯定確認(rèn):在收到一個正確的分組時,向發(fā)送主機發(fā)送一個分組,用于告訴發(fā)送主機剛才發(fā)送的分組正確送達。
否定確認(rèn):接受到一個分組后,向主機發(fā)送一個分組,這個分組的含義被雙方解釋為具有某些否定意義。
停等協(xié)議:在作為接收方的一端未正確的接收到本次發(fā)送的分組時,發(fā)送方不會發(fā)送下一個分組的協(xié)議。
自動重傳請求協(xié)議:基于肯定確認(rèn)或否定確認(rèn)來實現(xiàn)重傳,以達到可靠數(shù)據(jù)傳輸?shù)膮f(xié)議被歸類于ARQ協(xié)議。
為什么在rdt2.x中序號只需要1bit即可?
我們在rdt2.x中引入序號是為了讓接收方檢測冗余分組,也就是說,一個可能出現(xiàn)冗余的分組所攜帶的序號,在這個分組被確認(rèn)無誤的接收前,不會被一個新的分組去使用即可。
簡單點說就是當(dāng)使用序號 0 時,不會有一個新的分組去使用序號 0。
例如:發(fā)送方發(fā)送了 分組0 ,這個分組無誤送達,可是接收方返回的 ACK 出現(xiàn)比特錯誤,此時發(fā)送方有限狀態(tài)機的狀態(tài)為等待 分組0 的確認(rèn)報文, 接收方狀態(tài)為等待 分組1 送達,此時不會有新的分組去使用序號0。
我們可以把1bit的序號看作一個環(huán):,循環(huán)使用這些序號,因為我們的協(xié)議是一個停等協(xié)議,為每一個分組分配一個序號的話,那么在未確定序號為
的分組是否被正確接收時,不會發(fā)送序號為
的分組,所以發(fā)送方的有限狀態(tài)機只會停在等待確認(rèn)分組 N 的狀態(tài)下,此時收到一個 ACK 或者 NAK 可以保證是對分組 N 進行確定的。
而接收方
即便是 rdt2.2 中的冗余 ACK ,仍然可以使用 1bit 的序號。假設(shè)發(fā)送方發(fā)送分組0,但在傳輸過程出現(xiàn)了比特錯誤,此時接收方會發(fā)送一個 ACK1 報文,此時發(fā)送方完全可以斷定是分組0出現(xiàn)了錯誤,而沒有什么其他含義。
有限狀態(tài)機的幾個狀態(tài):
首先,發(fā)送方有四個狀態(tài),其中兩個為等待 ACK 的狀態(tài),即等待 分組0 和 分組1 的確定報文的狀態(tài),只有接收到一個含義為確定分組 n 被正確接收的報文時,發(fā)送方才會進入下一個狀態(tài)。
如果接收到一個表示發(fā)送的分組出錯的報文或有比特錯誤的確認(rèn)分組時,那么我們使發(fā)送方直接重傳這個分組,繼續(xù)在此狀態(tài)下等待對這個分組的確認(rèn)。(這是我們采取的重傳策略)
而接收方只有兩個狀態(tài),等待 分組0 和 等待 分組1的兩個狀態(tài)。
在只有比特錯誤的信道上可能出現(xiàn)的事件:
- a. 分組發(fā)送過程中無誤,且ACK報文無誤。
- b. 分組比特錯誤,接收方通過冗余校驗碼檢測到比特錯誤,并返回一個NAK報文,NAK報文無錯。
- c. 分組比特錯誤,接收方通過冗余校驗碼檢測到比特錯誤,并返回一個NAK報文,NAK報文出錯。
- d. 分組無錯,ACK報文比特錯誤,發(fā)送方無法識別這個報文的含義,不知道自己剛才所發(fā)送的分組是否被正確接收。
下面來對每個事件所產(chǎn)生的結(jié)果進行分析,這是也是對有限狀態(tài)機邏輯設(shè)計:
(為了使協(xié)議更具有通用性,所以下面我們使用 n 來代替 0 或者 1 這兩個序號)
a. 由于分組正確接收,且發(fā)送方得知了此消息, 故接收方和發(fā)送方有限狀態(tài)機進入 (n + 1) mod 2 狀態(tài),等待下一個分組的發(fā)送。
b. 由于發(fā)送的分組產(chǎn)生了錯誤,所以接收方會等到這個分組的重傳,不會進入下一狀態(tài)。而發(fā)送方接受到一個 NAK 分組后保持原狀態(tài),并重傳這個分組,等待對這個分組的確認(rèn)。
c. 由于發(fā)送的分組產(chǎn)生了錯誤,所以接收方會等到這個分組的重傳,不會進入下一狀態(tài)。而發(fā)送方接受到一個出錯的確認(rèn)報文,并不知道自己所發(fā)送的分組是對是錯,根據(jù)我們的策略,這里發(fā)送方直接重傳,然后等待一個 ACK 。
e. 分組沒有出錯,被接收方接受,接收方進入等待序號 (n + 1) mod 2 的狀態(tài),同時返回一個 ACK 。但是 ACK 在發(fā)送過程中出現(xiàn)了比特錯誤,所以發(fā)送方不知道自己所發(fā)的分組是否正確接收,根據(jù)策略,發(fā)送方重發(fā)分組 n,并等待對分組 n 的確認(rèn),自然也不會進入發(fā)送序號為 (n + 1) mod 2 的狀態(tài)。
由于先前接收方已經(jīng)接收了分組 n ,所以發(fā)送方重發(fā)的這個分組就是一個冗余分組,不過接收方可以通過序號來辨識出這是一個冗余分組,即在等待(n + 1) mod 2 分組狀態(tài)下,接收到一個序號為 n 的分組,接收方就認(rèn)定為是一個冗余分組,因為在只有比特錯誤的信道模型中,這種情況只可能是 ACK 出了錯誤。
綜上所述,接收方在等待 ACK 時,接收到了 NAK 或者出錯的確認(rèn)報文,就可以重傳。而接收方是在等待 分組N 狀態(tài)下,可能會接收到錯誤的 分組N, 此時返回一個 NAK 即可,還有可能接收到一個 分組 (N-1) mod 2, 此時只可能是之前的* ACK* 出現(xiàn)比特錯誤,接收方知道這種情況發(fā)生原因,所以在這種情況下就返回一個 ACK,使得接收方進入下一狀態(tài)。
在rdt2.2中,可以使用冗余 ACK 來代替 NAK ,是因為在發(fā)送方使用序號 N 時,不會有一個新的分組再次使用序號 (N + 1) mod 2 = (N - 1) mod 2,所以一個冗余的 ACK 送達,發(fā)送就可以明確的知道分組 N 出現(xiàn)了比特錯誤。
所以在發(fā)送方一端,可以直接將觸發(fā)重傳的事件由接收到 NAK 改為接收到 冗余ACK。
而在接收方就有些巧妙了,在等待 分組N 送達狀態(tài)下:
- 接收到出現(xiàn)比特錯誤的 分組N,此時發(fā)送方在等待 ACK N狀態(tài)下,接收方要返回一個冗余的 ACK (N - 1) mod 2,來通知發(fā)送方重傳 分組N。
- 接收到冗余 分組ACK (N - 1) mod 2,此時原因很明確,上面已經(jīng)說了,是因為對分組的確認(rèn)報文出現(xiàn)了比特錯誤。此時接收方停在等待 ACK (N - 1) mod 2 狀態(tài),所以要返回一個失序的 ACK,讓發(fā)送方進入下一狀態(tài)。
- 當(dāng)對上一個分組的確認(rèn)報文出錯時,發(fā)送方重傳這個分組,接收方可能接收到出現(xiàn)比特錯誤的 分組ACK (N - 1) mod 2(這里我們假設(shè)接收方在 等待 分組N 狀態(tài)下)。
因為分組出現(xiàn)了比特錯誤,所以接收方不知道這個分組究竟是一個冗余分組,還是一個新的分組。這也是接收方有限狀態(tài)機最巧妙的地方,此時可以發(fā)送一個 ACK (N - 1) mod 2(對于接收方來說,這是冗余的,因為在進入 N 狀態(tài)前,一定發(fā)送過一個 ACK (N - 1) mod 2 ),這不會使有限狀態(tài)機出現(xiàn)任何邏輯錯誤。
假設(shè)這個比特錯誤的分組是一個冗余分組,那么發(fā)送方此時在等待 ACK (N - 1) mod 2 狀態(tài)下,即便發(fā)送方重發(fā)的分組時錯誤的,因為接收方此前已經(jīng)正確收到了一個 分組(N - 1) mod 2,所以接收方可以使發(fā)送方直接進入下一狀態(tài)。
另外一種情況是這個比特錯誤的分組是一個新的分組,所以發(fā)送方應(yīng)該在 等待 ACK N 狀態(tài)下,此時接收方發(fā)送一個 ACK (N - 1) mod 2,自然而然使得發(fā)送方重傳這個分組了。
所以,在接收方收到一個錯誤的分組時,或是收到一個失序的分組時,都可以發(fā)送一個冗余 ACK 來作為回應(yīng),這不會產(chǎn)生任何邏輯錯誤。