一般 package 傳輸為停止並等待協定(Stop-and-wait)
有著通道使用率極低的問題。
GBN(Go-Back-N)
及 SR(Selective Repeat)
兩種協定避免了此問題。
效果上 SR > Go-Back-N > Stop-and-wait。
接下來分別對 GBN、SR、TCP 三者作說明:
GBN(Go-Back-N) 回溯 N
- GBN 接收端無需暫存任何順序不正確的封包,因為 GBN 傳送端會重送所有未經確認的封包。
- GBN 的單一封包錯誤,將導致需重送大量無需重送的封包,這是它的缺點之一。
GBN 傳送端重點
- 累積式確認:收到來自接收端回傳序號 n 的 ACK,表示小於 n 的封包都已經正確收到。
- 使用一個 Timer:綁定最早送出且未經確認的封包(Base)。
- 逾時事件:Timeout 時,若還未收到最早送出封包所回傳的確認,則重送所有未經確認的封包
base ~ (nextseqnum - 1)
。 - 收到順序不正確的 ACK:不做任何事情。
- 收到順序正確的 ACK:
- 將 base 設定為 ACK 的序號+1,造成窗格滑動,因此又稱
窗格滑動協定(Sliding-Window)
。 - 若還有可用封包可傳送的請況下,則重新啟動Timer。
- 傳送新的封包。
- 將 base 設定為 ACK 的序號+1,造成窗格滑動,因此又稱
情境舉例
設窗格大小為 3,且目前送出序號 0、1、2 封包,下個時間點收到 0 的 ACK 則窗格從原本的 [0、1、2] 滑動成 [1、2、3], 然後送出序號 3 的封包。
GBN接收端重點
- 收到正確順序的封包事件:回傳該封包序號的 ACK 給傳送端。
- 收到錯誤順序的封包事件:回傳最後一次收到正確序號的 ACK 給傳送端。
SR(Selective Repeat) 選擇性重複
- SR 傳送端只重送接收端未正確收到的封包,可能是遺失或毀損。
- SR 會將脫序的封包暫存。
- SR 的傳送端、接收端雙方的 window
位置
各自不同。 - SR 窗格大小必須等於有限序號大小的一半。
為什麼窗格大小必須是序號大小的一半?
有限序號 0、1、2、3,窗格大小為 3,接收端收到 0、1、2,所以接收端的窗格觀點會從 [0、1、2]、3、0、1、2… 變成 0、1、2、[3、0、1]、2…。
此時假設接收端回傳給傳送端的 ACK 遺失時,將造成傳送端等待逾時,而重送第一批的 0、1、2 給接收端;這時候的接收端想 要的是第二批的 0、1 以及第一批的 3,會有錯亂的問題,要避免此問題發生,就必須讓窗格大小是序號的一半,往下看下一個例子。
同樣的情境,將窗格大小改為 2,接收端收到 0、1,接收端窗格觀點就會從 [0、1]、2、3、0、1、2…變成 0、1、[2、3]、0、1、2。 若回傳給傳送端的 ACK 遺失時,傳送端等待逾時會重送第一批的 0、1,這時候接收端就不會有前一個例子錯亂的問題。
SR傳送端重點
- 逾時事件:每個封包都綁有 timer,當各個封包的 ACK 逾時未收到,則重送該封包。
- 收到 ACK:
- 標記對應序號的封包為已確認。
- 若收到的 ACK 序號是 Base,則將 Base 移動到下個最小未經確認的封包上。
- 若窗格移動到了尚未傳送的封包上,則同時送出這些未被送出的可用封包。
對於第二點的範例
目前送出 0、1、2、3、4,已收到的 ACK 為1、2,因為序號 0 尚未收到 ACK,所以 base 會停留在 0,一旦之後收到 ACK 0,base會直接跳到 3,因為此時 0、1、2 都已經確認過了。
SR接收端重點
- 接收到目前 window 內任一封包:
- 回傳收到的序號之 ACK 給傳送端。
- 若收到的序號不是 base,則將封包暫存。
- 若收到的序號是 base,將 base 與其後連續已收到的封包交由上層,並將 window 移動到最小預期收到的 位置上。例如:接收端窗格為 0、1、2、3、4,此時收到 1、2、3,將它們暫存起來,之後收到 0(base) ,則將 0、1、2、3 一次交給上層,並將 window 移動到4。
- 收到 window 之前的封包事件:再傳一次收到的序號之 ACK 給傳送端,倘若不傳,傳送端的 window 將永遠無法移動。 (之所以收到 window 之前的封包,表示上一次回傳給傳送端的 ACK 可能遺失了, 使得傳送端等到 timeout 仍沒收到 ACK 才再發一次之前的封包過來。)
- 收到其它封包的事件:忽略該封包。
TCP(Transmission Control Protocol)
- TCP 傳送端只需要維護「最小已送出未經確認的封包之序號」及「下一個要傳送的封包之序號」
- TCP 最多只重送一筆區段
- TCP 之 ACK 與 GBN、SR 兩者的 ACK 不同,TCP 傳送端所發出的 ACK,表示期待下一次要收到的封包之序號, 而 GBN、SR 的 ACK 用來告知已經收到的封包之序號。
- TCP 同 SR 會將脫序的封包暫存。
- TCP 為累積式確認(也有某種 TCP 修正稱選擇性確認)。
TCP傳送端重點
- 逾時事件:重送封包。
- 收到重複三次 ACK(
Duplicated Ack
):重送封包,又稱快速重送
。因為接收端總是收到 非預期的封包,而連續回傳希望收到的封包之序號,此時傳送端就會立刻重送接收端所預期的封包 ,這將會在 timeout 前就送出。
TCP 接收端重點
- 預期封包抵達事件:回傳下一次期望收到的封包序號 ACK。
- 非預期封包抵達事件:暫存封包,送出期望收到的封包之序號 ACK。
比較 GBN、SR、TCP 的範例
假設 timeout 時間內足夠傳送5筆區段,包含回應的 ACK 被傳送端收到。 傳送端傳送給接收端的 5 個區段,當中有 2 個區段遺失,且最後接收端會收到所有的區段, 在上面兩個前提下,下列為 GBN、SR、TCP 三者傳送端、接收端的比較:
- GBN
- 傳送端:共送出9個區段(1、2、3、4、5)和補送的(2、3、4、5)
- 接收端:回應8個ACK(1、1、1、1、2、3、4、5)
- SR
- 傳送端:共送出6個區段(1、2、3、4、5)和補送的(2)
- 接收端:共回應5個ACK(1、3、4、5、2)
- TCP
- 傳送端:共送出6個區段(1、2、3、4、5)和快速重送的(2)
- 接收端:共回應5個ACK(2、2、2、2、6)
附註
GBN、SR 觀點的 Window
Base 表示最久未經確認的封包,nextseqnum 是窗格內最小未被傳送, 由上圖可定義出四種區段:
- [0, base - 1] 區段:已傳輸,且已經過確認的區段。
- [base, nextseqnum - 1] 區段:已傳輸,未經確認的區段。
- [nextseqnum, base + n + 1] 區段:窗格內可使用但尚未送出的區段。
- [base + n, ~] 區段:不在窗格內,也不可使用的區段。
GBN 傳送端觀點範例
假設以下號碼分別代表封包的狀態:
- 已傳送已收到確認
- 已傳送未收到確認
- 可使用尚未傳送
- 不可使用
111222333444
可推得:
- 第一個 2 為 base。
- 窗格範圍:222333,窗格大小為6。
- GBN分隔明顯,window 內只有 2、3 且為連續。
SR傳送端觀點範例
假設以下號碼分別代表封包的狀態:
- 已傳送已收到確認
- 已傳送未收到確認
- 可使用尚未傳送
- 不可使用
111221121233344
可推得:
- 第一個 2 為 base。
- 窗格範圍:2211212333,窗格大小為 10。
- SR 的 window 內交錯著 2、1。
- 窗格範圍:從最小未經確認的封包~最大可用的送出封包。
SR接收端觀點範例
假設以下號碼分別代表封包的狀態:
- 已收到
- 預期卻未收到
- 未依序但已回傳ACK
- 窗格內仍未收到
- 不可使用
555677888999
可推得:
同前 SR 敘述 最小預期收到的位置
,
因此窗格範圍為:677888,窗格大小為 6(與上一個傳送端沒有對應關係,不要混著看)。