篇首語:回退N步(GBN)和選擇重傳(SR)是解決流水線的差錯恢復的兩種基本方法。
本篇我們先來看看GBN。
首先我們了解滑動窗口的概念:滑動窗口的作用是控制流量,它可以存在於接收端和發送端。以發送窗口為例,其基本原理就是在任意時刻,發送方都維持了一個連續的允許發送的幀的序號。不同的滑動窗口協議窗口大小一般不同。發送方窗口內的序列號代表了那些已被發送但還未被確認的幀和未被發送但可用於發送的幀。(注:發送窗口和接收窗口的序號的上下界甚至大小不一定要一樣)同時我們規定滑動窗口的首個序號,即最早未確認的分組,為base序號,而規定最早的未被發送但可用於發送的序號為nextseqnum序號(nextsequm-base<=N)。
現在再來看回退N步。我們將各個分組編號,設滑動窗口大小為N。發送方一次傳輸N個分組過去,當接收方接受到其中一個分組,接收方會判斷分組序號是否為上一個已確認分組的序號+1。是的話,接收方返回ACK給發送端並提交分組給上一層。發送端收到ACK后,再比較是否和其base序號相同,相同則滑動窗口向后移動一位。
上述中出現了兩次是否判斷,分別在接收方和發送方。現在我們看看如果出現否的情況。
1.如果接收方接受到的分組不是比提交的分組大1(或根本沒接收到什么分組),說明在該分組之前的分組遺失了,於是接收方會丟棄該分組,也不返回對應的ACK。發送方長時間接受不到所需ACK,會導致其定時器超時。
2.如果發送方收到的ACK序號與其base不同,說明在其之前的ACK遺失了,但滑動窗口依舊會滑動,不用重傳,因為一旦收到了某序號的ACK,說明在此之前的分組接收方都已確認接收。
但如果發送方沒接受到此后任何的ACK,導致超時,則會引起重傳,比如這種情況會發生在整個傳輸中的最后一個分組身上。
而上述兩者情況一旦引起定時器超時,最終造成的反應方都是發送方,即發送方重新發送分組(從滑動窗口中最早未確認的分組開始)。(重傳是保證可靠數據傳輸的靈丹妙葯)
那么定時器有是什么東西呢?首先我們明確一下GBN只有一個定時器,這個定時器計時的對象始終是發送方滑動窗口的base,當base+1,定時器就會刷新計時。(注:定時器的啟動和結束的判斷依據都是base == nextseqnum)
以上就是GBN的運行基本原理。
我們可以看到,一旦出現錯誤,接收方會丟棄所有失序的分組,而發送方則會從滑動窗口中的第一個未確認的(base)分組開始重傳。值得肯定的是,這種方法對接收方是十分友好的,他不要求接受方緩存任何失序的分組,而是靠發送方維護滑動窗口(上下界和nextseqnum的位置)來保障數據的可靠傳輸。但缺點也是十分明顯的,一旦某個分組(或)丟失,則可能導致同一個窗口發送過來的分組都會被丟棄,這樣不僅了網絡的浪費,同時不必要的重傳也會增大出錯率,所以,如果信道傳輸質量很差,導致誤碼率較大時,后退N幀協議不一定優於停止-等待協議。
這里建議大家看看一個java小程序,來實操一下GBN的過程,可能還會發現其他意外情況。
錯誤之處,還望指出。