背景
如果過多的源同時以很快的速度傳送大量的數據包,而此時接收方並沒有如此高的接收數據的能力,因此極易導致網路的擁塞。所以,為了控制傳送方的傳送速度,防止傳送方並考慮到受傳送緩衝區大小的制約等,要求對傳送方已發出但尚未經確認的幀的數目加以限制,同時使網路的傳輸效率得到提高,滑動視窗協定應運而生,它使得傳送方可以在未收到確認的情況下,同時傳送多個數據分組,由此大大提升了網路吞吐量。
在任何基於自動重發請求進行錯誤控制的通信協定中,接收方必須確認收到的數據包。 如果傳送方在合理的時間內沒有收到確認,則重發數據。沒有聽到確認的傳送方不知道接收方是否實際接收到分組(數據可能在傳輸中丟失或損壞)。 如果錯誤檢測顯示損壞,則數據包將被接收方忽略,並且不會傳送確認。 因為網路傳輸的時延,將有大量時間被用於等待確認,導致傳輸效率低下。
定義
傳輸的每個部分被分配唯一的連續序列號,接收方使用數字並以正確的順序放置接收到的數據包,丟棄重複的數據包並識別丟失的數據。
協定中規定,對於視窗內未經確認的分組需要重傳。這種分組的數量最多可以等於傳送視窗的大小,即滑動視窗的大小n減去1(因為傳送視窗不可能大於(n-1),起碼接收視窗要大於等於1)。
滑動視窗協定必須保證數據包的按序傳輸,傳送視窗中的序列號代表已傳送但尚未收到確認的數據包,傳送視窗可持續地維持一系列未經確認的數據包,因為傳送方視窗內的數據包可能在傳輸過程中丟失或損壞,所以傳送過程必須把傳送視窗中的所有數據包保存起來以備重傳。傳送視窗一旦達到最大值,傳送過程就必須停止接收新的數據包,直到有空閒快取區。接收視窗外的數據包都要丟棄,當序列號等於接收視窗下限的數據包到達時,把它提交給應用程式並向傳送端傳送確認,接收視窗向前移動一位。傳送視窗和接收視窗上下限無需相同,大小也無需相同,但接收視窗大小需保持固定,傳送視窗大小可隨著數據包而改變。
工作機制
工作原理
通過限制在任何給定時間可以傳送或接收的數據包的數量,滑動視窗協定允許使用固定大小的序列號傳送無限數量的數據包。傳送方側的術語“視窗”表示接收方尚未確認的分組總數的邏輯邊界。接收方在每個確認包中通知傳送器當前的最大接收緩衝區大小(視窗邊界)。 TCP報頭使用16位欄位向傳送方報告接收視窗大小。因此,可以使用的最大視窗是2^16 = 64千位元組。在慢啟動模式下,傳送器以低分組計數器開始,並且在從接收方接收到確認分組之後增加每個傳輸中的分組數量。對於接收的每個ACK分組,該視窗通過一個分組(邏輯地)滑動以傳送一個新分組。當達到視窗閾值時,傳送器傳送一個包,用於接收到的一個ACK分組(確認分組)。如果視窗限制為10個數據包,則在慢啟動模式下,傳送器可以開始傳送一個數據包,後跟兩個數據包(傳送兩個數據包之前必須接收一個數據包),其次是三個數據包等等,直到10個數據包。但是在達到10個分組之後,進一步的傳輸被限制為一個接收到的一個分組傳送的分組。在仿真中,看起來好像視窗對於接收到的每個ACK分組移動一個分組距離。在接收方側,視窗也會為接收到的每個數據包移動一個數據包。滑動視窗方法可以確保網路上的交通擁堵得以避免。套用層仍將提供傳輸到TCP的數據,而不用擔心網路流量擁塞問題,因為傳送方和接收方的TCP實現分組緩衝區的滑動視窗。視窗大小可能根據網路流量而動態變化。
操作
傳送方和接收方分別具有當前序列號nt和nr。它們各自還有一個視窗大小wt和wr。視窗大小可能會根據網路流量的變化而有所不同,但是在更簡單的實現中它們是固定的。視窗大小必須大於零才能進行任何操作。
通常情況下,nt是要傳送到下一個分組,即尚未傳送的第一分組的序列號。同樣地,nr尚未收到的第一個分組的序列號。這兩個序列號會隨著時間逐漸增加。
接收方還可以跟蹤未接收到的最高序列號,變數ns比接收到的最高序列號還多一。對於僅接受數據包(wr = 1)的簡單接收方,這與nr相同,但如果wr> 1,則可以更大。注意區別:已經收到nr以下的所有數據包,沒有接收到ns以上的任何數據包,在nr和ns之間,已經收到一些數據包。
當接收方接收到一個數據包時,它會適當地更新其變數,並用新的nr傳送確認。傳送方跟蹤其收到的最高確認。傳送方知道已經接收到但不包括na的所有分組,但是對於na和ns之間的分組是不確定的,即na≤nr≤ns。
並且序列號總是符合na≤nr≤nx≤nt≤na+wt的規則,證明如下:
na≤nr:傳送器接收到的最高確認不能高於接收方確認的最高nr。
nr≤ns:完全接收的數據包的範圍不能超出部分接收的數據包的結尾。
ns≤nt:接收到的最高報文不能高於傳送的最高報文。
nt≤na + wt:傳送的最高數據包同時受到接收到的最高確認和傳送視窗大小的限制。
傳送方操作
每當傳送方具有要傳送的數據時,它可以在最新的確認na之前傳輸序列號高達wt數據包。也就是說,只要nt<na + wt,它可以傳送分組號nt。
在沒有通信錯誤的情況下,傳送方很快就會收到所有傳送的數據包的確認信息,這等於nt。如果在合理的延遲之後不會發生這種情況,則傳送方必須在na和nt之間重傳數據包。
接收方操作
每次接收到一個編號為x的數據包時,接收方檢查它是否落入接收視窗,nr≤x<ns + wr。 (最簡單的接收方只需要跟蹤一個值nr =ns。)如果它落在視窗內,接收方接受它。如果編號為nr,則接收序列號增加1,並且如果先前接收和存儲更多的連續分組,則可能更多。如果x> nr,則存儲數據包直到接收到所有先前的數據包為止。如果x≥ns,後者更新為ns = x + 1。
如果數據包的序列號不在接收視窗內,則接收方將丟棄該數據包,並且不修改nr或ns。無論數據包是否被接受,接收方傳送包含當前nr的確認。 (確認還可以包括關於nr或ns之間接收的附加數據包的信息,但這只能幫助效率。)
請注意,沒有必要讓接收視窗wr大於傳送視窗wt,因為不需要擔心接收到永遠不會傳送的數據包;有用範圍為1≤wr≤wt。
套用場景
滑動視窗協定以基於分組的數據傳輸協定為特徵。因此該協定適用於對按順序傳送分組的可靠性要求較高的環境,例如在數據鏈路層(OSI模型)以及傳輸控制協定(TCP)中。
增強應答的鏈路層重傳,在長線傳輸中,因軟故障造成的訊息傳輸錯誤占據了絕大部分,對於這些問題的解決可以是系統的可靠性大大提高。這種機制,向通過實現簡單、檢突發錯誤能力高的CRC碼的校驗進行錯誤檢查,再由相應的滑動視窗協定實現重傳恢復。
套用實例
[1] 停止等待協定(stop-and-wait)
這時接受方的視窗和傳送方的視窗大小都是1,1個比特就夠表示了,所以也叫1比特滑動視窗協定。傳送方這時自然傳送每次只能傳送一個,並且必須等待這個數據包的ACK,才能傳送下一個。雖然在效率上比較低,頻寬利用率明顯較低,不過在網路環境較差,或是頻寬本身很低的情況下,還是適用的。
存在的問題是,當傳送方交替傳送標記為“奇數”和“偶數”的數據包。 傳送的確認同樣為“奇數”和“偶數”。 假設已經傳送了奇數分組的傳送方沒有收到奇數確認,而是立即傳送下一個偶數分組,在此之後它可能會收到一個確認,為“下一個奇數包”。這將使傳送方出現不確定因素:接收方有可能接收到這兩個數據包,或者兩者都沒接收到。
[2]回退n步協定(GO-BACK-N)
由於停止等待協定效率太低,因此有了回退n-步協定,這也是滑動視窗協定真正的用處,這裡傳送的視窗大小為n,接受方的視窗仍然為1。具體看下面的圖,這裡假設n=9: 首先傳送方一口氣傳送10個數據幀,前面兩個幀正確返回了,數據幀2出現了錯誤,這時傳送方被迫重新傳送2-8這7個幀,接受方也必須丟棄之前接受的3-8這幾個幀。 後退n協定的好處無疑是提高了效率,但是一旦網路情況糟糕,則會導致大量數據重發,反而不如上面的停等協定。
存在的問題在於,假設我們使用3位序列號,這是
HDLC的典型值。 這使得N =
= 8。 由於wr = 1,我們必須限制wt≤7。 這是因為在傳送7個數據包之後,有8個可能的結果:0到7個數據包都可能被成功地接收。 這有8種可能性,傳送方在確認中需要足夠的信息來區分它們。如果傳送方傳送8個數據包而不等待確認,則可能會發現自己存在和停止等待協定一樣的問題:這意味著所有8個數據包都可能被成功接收,亦或是一個都沒有被成功接收。
[3]選擇重傳協定(selective repeat)
後退n協定的另外一個問題是,當有錯誤幀出現後,總是要重發該幀之後的所有幀,毫無疑問在網路不是很好的情況下會進一步惡化網路狀況。
重傳協定便是用來解決這個問題。原理也很簡單,接收端總會快取所有收到的幀,當某個幀出現錯誤時,只會要求重傳這一個幀,只有當某個序號後的所有幀都正確收到後,才會一起提交給高層套用。重傳協定的缺點在於接受端需要更多的快取。
存在的問題在於:最為普遍的HDLC協定使用3位序列號,並具有選擇性重複的可選條件。但是,如果使用選擇性重複,則必須保持nt +nr≤8的要求;如果wr增加到2,則wt必須降低到6。假設wr = 2,但是與wt = 7一起使用未修改的發射機。進一步假設接收器以nr = ns = 0開始。
現在假設接收器看到以下一系列數據包(均為模8):
0 1 2 3 4 5 6(暫停)0
由於wr = 2,接收方將接受並存儲最終的數據包0(在系列中認為它是數據包8),同時請求重發數據包7。.然而,傳送方也不可能接收到任何確認,並且在後一種情況下,接收機將接收錯誤的分組作為分組8。解決方案是傳送方限制wt≤6。通過這種限制,接收方在接收到分組6後知道傳送方的na≥1,並且因此編號為0的後續分組必須是分組8。如果所有確認丟失,則傳送方將不得不在分組5之後停止。
注意事項
(1)傳送方不必傳送一個全視窗大小的數據。
(2)來自接收方的一個報文段確認數據並把視窗向右邊滑動,這是因為視窗的大小是相對於確認序號的。
(3)視窗的大小可以減小,但是視窗的右邊沿卻不能夠向左移動。
(4)接收方在傳送一個ACK前不必等待視窗被填滿。
協定改進
由於“滑動視窗”協定的性能取決於視窗大小和網路接收數據包的速度,在流量不穩定的環境中,性能下降甚至可能會使網路發生衝突。 為了避免和提供端到端流量控制,可以建議“慢啟動”協定。
對於該協定的改進主要集中在如何減少TCP報文重傳方面,目前在TCP中每傳輸一個報文都要求接收方進行確認,大量短而頻繁的確認報文給網路帶來了很多開銷。因此採取了延遲ACK策略來減少ACK的數量,就是接收方收到一個報文以後,不會立即傳送ACK,而是等待1~200ms,這期間若有回送數據報文就捎帶確認,但收到兩個連續數據報文或者等待逾時則傳送一個獨立確認。有效減少了ACK的數量,改善了TCP的整體性能。