擁塞控制 慢啓動 快恢復 擁塞避免

1.  慢開始和擁塞避免

 

擁塞窗口:

       發送方維持一個擁塞窗口 cwnd ( congestion window )的狀態變量。擁塞窗口的大小取決於網絡的擁塞程度,並且動態地在變化。發送方讓自己的發送窗口等於擁塞。

慢開始算法

        在剛剛開始發送報文段時,先把擁塞窗口 cwnd 設置爲1個最大報文段MSS的數值,而後每收到一個對新的報文段的確認,就把擁塞窗口增加1個MSS的數值,這樣擁塞窗口cwnd的值就隨着傳輸輪次(一個輪次即發送完一個cwnd的MSS)呈指數級增長,事實上,慢啓動的速度一點也不慢,只是它的起點比較低一點而已。用這樣的方法逐步增大發送方的擁塞窗口 cwnd ,可以使分組注入到網絡的速率更加合理。

        一個傳輸輪次所經歷的時間其實就是往返時間RTT,不過“傳輸輪次”更加強調:把擁塞窗口cwnd所允許發送的報文段都連續發送出去,並收到了對已發送的最後一個字節的確認。

慢開始門限ssthresh:

        爲了防止擁塞窗口cwnd增長過大引起網絡擁塞,還需要設置一個慢開始門限ssthresh狀態變量(如何設置ssthresh)。慢開始門限ssthresh的用法如下:

        當 cwnd < ssthresh 時,使用上述的慢開始算法。

        當 cwnd > ssthresh 時,停止使用慢開始算法而改用擁塞避免算法。

        當 cwnd = ssthresh 時,既可使用慢開始算法,也可使用擁塞控制避免算法。

擁塞避免算法

        當cwnd >= ssthresh時,就會進入“擁塞避免算法”,讓擁塞窗口cwnd緩慢地增大,每收到1個ACK擁塞窗口cwnd = cwnd + 1/cwnd,即每經過一個傳輸輪次就把發送方的擁塞窗口cwnd加1。這樣擁塞窗口cwnd按線性規律緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢得多。

網絡擁塞:

        無論在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(超時計時器RTO時限已到但還沒有收到確認),就要把慢開始門限ssthresh=cwnd/2(>=2),然後把擁塞窗口cwnd=1,執行慢開始算法。這樣做的目的就是要迅速減少主機發送到網絡中的分組數,使得發生擁塞的路由器有足夠時間把隊列中積壓的分組處理完畢。

        如下圖,用具體數值說明了上述擁塞控制的過程。現在發送窗口的大小和擁塞窗口一樣大。

 

        1). 當TCP連接進行初始化時,把擁塞窗口cwnd置爲1MSS,慢開始門限的初始值設置爲16個MSS,即 ssthresh = 16 。

        2). 在執行慢開始算法時,擁塞窗口 cwnd 的初始值爲1。以後發送方每收到一個對新報文段的確認ACK,就把擁塞窗口cwnd加1,則每個傳輸輪次擁塞窗口cwnd翻倍,因此在慢開始階段擁塞窗口cwnd 隨着傳輸輪次按指數規律增長。

        3). 當擁塞窗口cwnd增長到慢開始門限值ssthresh時(即當cwnd=16時),就改爲執行擁塞控制算法,每個傳輸輪次擁塞窗口cwnd加1,因此在擁塞控制階段擁塞窗口cwnd 隨着傳輸輪次按線性規律增長。

        4). 假定擁塞窗口的數值增長到24時,超時計時器RTO時限已到但還沒有收到確認,則認爲網絡出現超時(這很可能就是網絡發生擁塞了)。更新後的ssthresh值變爲ssthresh/2=12,擁塞窗口cwnd=1,然後回到第2)步繼續運行。

        強調:“擁塞避免”並非指完全能夠避免了擁塞。利用以上的措施要完全避免網絡擁塞還是不可能的。“擁塞避免”是說在擁塞避免階段將擁塞窗口控制爲按線性規律增長,使網絡比較不容易出現擁塞。

 

2. 快重傳和快恢復

 

快重傳算法:

        快重傳算法首先要求接收方每收到一個失序的報文段就立即發出重複確認(爲的是使發送方及早知道有報文段沒有到達對方),然後若是發送方接收到3個重複確認ACK,則啓動快重傳算法。

        接收方收到了M1和M2後都分別發出了確認。現在假定接收方沒有收到M3但接着收到了M4、M5、M6。顯然,接收方不能確認M4、M5、M6,因爲M4、M5、M6是收到的失序報文段。按照快重傳算法的規定,接收方應及時發送對M2的重複確認,這樣,發送方共收到了接收方的四個對M2的確認,其中後三個都是重複確認。

        快重傳算法還規定,發送方只要一連收到三個重複確認就應當立即重傳對方尚未收到的報文段M3,而不必繼續等待M3設置的重傳計時器RTO到期。

 

快速恢復算法:

       TCP Reno算法定義在RFC5681。快速重傳和快速恢復算法一般同時使用。快速恢復算法認爲,你還有3個Duplicated Acks說明網絡也不那麼糟糕,所以沒有必要像RTO超時那麼強烈,並不需要重新回到慢啓動進行,這樣可能降低效率。所以協議棧會做如下工作:

        1). 擁塞窗口減半cwnd=cwnd/2

        2). 慢開始門限ssthresh=cwnd(減半後的值)

然後啓動快速恢復算法:

        1). 設置cwnd = ssthresh+ack個數(一般情況下會是3個Dup Acks),然後重傳指定的數據包;

         2). 如果再次收到Dup Acks,則cwnd=cwnd+1, 並且在條件允許的情況下發送下一個報文段(非重傳報文段)

        3). 如果收到新的ACK, 則快速恢復算法結束,設置cwnd = ssthresh, 進入擁塞避免階段

        上面這個算法是有問題,那就是——它依賴於3個重複的Acks。因爲,3個重複的Acks並不代表只丟了一個數據包,很有可能是丟了好多包。但這個算法只會重傳一個,而剩下的那些包只能等到RTO超時,於是,進入了惡夢模式——超時一個阻塞窗口減半,多個超時會超成TCP的傳輸速度呈級數下降,而且也不會觸發快速恢復算法了。

TCP New Reno算法:

        這個算法是Reno算法的改進,沒有使用SACK機制
        當發送者這邊收到了3個Duplicated Acks,進入快速恢復模式,開始重傳重複acks指示的那個包。如果只有這一個包丟了,那麼,重傳這個包後回來的ack會把整個已經被髮送方傳輸出去的數據的ack返回來。如果沒有的話,說明有多個包丟了。我們叫這個ACK爲Partial ACK。 
        一旦發送方這邊發現了Partial ACK出現,那麼發送方就可以推理出來有多個包被丟了,於是繼續重傳滑動窗口裏未被ack的第一個包。直到再也收不到了Partial Ack,才真正結束快速恢復這個過程。

-----------------------------------------------------------------------------------------------------------------------

        接收方根據自己的接收能力設定了接收窗口rwnd,並把這個窗口值寫入TCP首部中的窗口字段,傳送給發送方。因此,接收窗口又稱爲通知窗口。因此,從接收方對發送方的流量控制的角度考慮,發送方的發送窗口一定不能超過對方給出的接收窗口rwnd 。

        發送方窗口的上限值 = min [ rwnd, cwnd ]

        當rwnd < cwnd 時,是接收方的接收能力限制發送方窗口的最大值。

        當cwnd < rwnd 時,則是網絡的擁塞限制發送方窗口的最大值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章