任何通訊協議在傳遞封包時都有可能因為外在因素導致封包遺失或是封包損毀導致傳送失敗,如果是不太重要的封包那還好,但如果是極度重要的資訊(轉帳, 密碼...) 的話,傳送失敗很有可能造成嚴重的後果,所以 Reliable Transmission 就誕生了,其目的就是為了保障傳遞封包的正確性與可靠性,詳細的內容就繼續看下去吧。
在傳遞封包的過程中會因為各種原因的干擾導致封包損毀,為了避免收到損毀的封包,通常會進行 CRC
的檢測,而也有一些封包會多添加資訊用於當錯誤發生時可以明確的知道錯誤發生在哪裡,但相對的這種作法的負擔也會比較高。
而如果今天某一個封包非常重要,那麼就需要再檢測到封包損毀的時候再次發送一次,這個行為就稱為 Reliable Transmission
,通常會用兩種方法確保 Reliable Transmission 行為。
Acknowledgements
代表當對方收到正確的封包的話,將會發送一個訊息用於告訴發送方他已收到正確的封包,由於回傳的訊息只是為了通知發送方確實收到封包,所以該訊息不會攜帶 data,故這種訊息稱為 control frame
。
如果今天發送方發送了一個封包但接收方完全沒收到的話,那就會造成發送方在等接收方的 Ack 而接收方也在等發送方的封包,為了避免這種情況,發送方在發送一個封包後會開啟一個計時器, 當計時器結束前都還沒收到接收方的回應時,那發送方就會在發送一次封包
。
傳輸封包時使用 Acknowledgements
和 timeout
機制可以確保接收方確實收到正確的資料,這個行為稱為 Automatic Repeat reQuest (ARQ)
當發送方發送了一個封包後會停止發送下一個封包並等待一段時間,當收到接收方的 Ack 後才會在發送下一個封包,如果在等待的時間內沒收到則會再次發送
當 Sender 發送一個封包後,在 timeout 的時間內接收到 Receiver 傳來的 Ack 代表這個封包正確的傳送到 Receiver。
當 Sender 發送的封包沒有送到 Receiver 那邊的話,Sender 就無法收到來自 Receiver 的 Ack,當時間超過 Timeout 的時間後,Sender 便會再次發送一次封包。
當 Sender 發送封包給 Receiver 後, Receiver 確實收到封包後回傳一個 Ack,但回傳的 Ack 發稱損毀導致 Sender 無法收到 Ack 而超過 timeout 時間導致 Sender 重送一次封包。
這種情況會導致 Receiver 會收到一次以上相同的封包,Reciver 將無法分辨收到的封包是否為相同的資料。
當 timeout 設定的時間太短或是 Receiver 的 Ack 被 delay 了,這樣就會導致 Sender 再次發送一次封包,導致 Receiver 接收到一次以上相同的封包
上面的例子中可以看到,如果 Ack 發生延遲或損毀都會發生 Sender 發送重複的封包,為了避免 Reciver 收到重複的封包,可以再封包中添加一個編號,這樣可以讓 Reciver 以該編號作為 id 進行驗證。
由於 Sender 每發送一次封包都需要等待 Receiver 的 Ack,會導致 Link 上只有一組封包再傳輸,無法有效地發揮 Link 的 capacity 而導致傳輸數率較差。
為了解決 Stop and Wait Protocol 所產生 一次只能傳遞一個封包
的問題,Sliding Window Protocol 由此誕生,這個 Protocol 一次可以發送多個封包,已達到傳輸效率提高的目的。
為了達到一次可以發送多個封包的目的,該 Protocol 會在發送的封包上多添加一個用於識別該封包身份的 id,稱為 SeqNum
,而 Sender 需要多負責紀錄三個參數
SeqNum
上面的 Gif 表示 Sender 端的 Sliding Window 是如何運作的:
SeqNum
SeqNum
![[img]https://i.imgur.com/sTGFcvH.gif/img
Receiver 回傳的 Ack 並不會按照順序的回傳給 Sender,所以以上面的 gif 來說, 2 號封包一直沒有收到 Ack 的情況下就不會發生 Sliding,必須等到收到封包 2 的 Ack ,而當接收到封包 2 的 Ack 後便會開始進行 Sliding 的動作。
為了接收到 Sender 發送的封包,Receiver 也需要控制三個參數以確保接收封包的正確性與穩定性。
SeqNum
必須是 Receiver 允許的,如果超過這個數量或 SeqNum
不對則不會接收該封包。SeqNum
最大值。SeqNum
。上面的 Gif 表示 Receiver 端的 Sliding Window 是如何運作
SeqNum
需要是 4 ~ 10SeqNum
的最大值)就變更為 4SeqNum
) 更改為 11如個今天收到的封包的 SeqNum
< LFR 或 SeqNum
> LAF 的話,Receiver 則會忽視這個封包不接收,只接收 LFR < SeqNum
< LAF 的封包。
Sender 發送的封包不會按照順序傳送給 Receiver,所以以上面的 Gif 來說,2 號封包一直沒有收到的情況下, Receiver 就不會發生 Sliding,必須等到確實收到了2 號封包才會發生 Sliding。
如果 Sender 一次可以發送多個封包,那相對的 Receiver 也要回復多個 Ack 表示接收的狀況,但是每一個封包都要回覆一個 Ack 其實也會影像效率,所以出現了一個新的 Ack 形式稱為 SeqNumToAck
,他回覆的 Ack 表示 Receiver 目前接收到的封包的 SeqNum
的最大值,簡單來說就是 SeqNum 小於這個 SeqNumToAck 的封包都已經收到了
,這樣就可以不用一個一個的回送 Ack 給 Sender。
如果 Receiver 收到的封包的 SeqNum
比 SeqNumToAck
還大的話,那 Receiver 依然還會發送 SeqNumToAck
給 Sender 而不是較大的封包的 SeqNum
Sender 發送 SeqNum = 1 的封包給 Receiver,當 Receiver 收到後回覆 SeqNumToAck = 2
代表 SeqNum = 2 以前(SeqNum = 1)的封包都收到了
如果 Sender 發送的 SeqNum = 2
的封包在發送過程中遺失了,那麼 Receiver 就不會回送 Ack 給 Sender
當 Sender 發送 SeqNum = 3 的封包給 Receiver,雖然 Receiver 有收到但是因為 SeqNum = 2 的封包遺失了,所以無法發送 SeqNumToAck = 4
。
因為如果發送了 SeqNumToAck = 4
的話,代表已經接收到了封包 1, 2, 3 (封包 2 已經遺失了)。
一樣的就算 Receiver 接收到了 SeqNum = 3 的封包,一樣因為 SeqNum = 2 的封包遺失了,所以只能發送 SeqNumToAck = 2
而當 SeqNum = 2
的封包發生 Timeout 而再次發送後,Receiver 才收到了 SeqNum = 2
的封包,這時才可以發送 SeqNumToAck = 5
表示 SeqNum = 5 之前的封包都收到了