簡介
** 擁塞 ** :即對資源的需求超過了可用的資源。當網絡中資源供應不足,導致出現資源競爭時,就會出現擁塞現象,擁塞會降低網絡性能和吞吐量。
** 擁塞控制 ** :通過控制數據注入到網絡中的速率來盡可能避免網絡出現擁塞,從而使網絡中的路由器或鏈路不致過載。前提:網絡能夠承受現有的網絡負荷。擁塞控制是一個全局性的過程,涉及到所有的主機、路由器,以及與降低網絡傳輸性能有關的其他因素。
** 流量控制 ** :流量控制所要做的就是抑制發送端發送數據的速率,以便使接收端來得及接收。是一個端到端的控制過程。
** 擁塞控制代價 ** :擁塞控制需要獲得網絡內部流量分布的信息。因此在實施擁塞控制之前,需要在結點之間交換信息和各種命令,以便選擇控制的策略和實施控制,這樣就產生了額外的開銷。擁塞控制還需要將一些資源分配給各個用戶單獨使用,使得網絡資源不能更好地實現共享。
控制算法
發送方控制擁塞窗口的 ** 原則 ** 是:只要網絡沒有出現擁塞,擁塞窗口就再增大一些,以便把更多的分組發送出去。但只要網絡出現擁塞,擁塞窗口就減小一些,以減少注入到網絡中的分組數。
慢開始
在 TCP 連接開始傳輸數據時,先將擁塞窗口 cwnd 設為 1 個 MSS(最大報文段),每當收到一個報文段的確認,就將 cwnd+1,因此,每經過一個傳輸輪次 RTT,cwnd 的大小就加倍,直至 cwnd 大小達到預設的慢開始門限值 ssthresh。
一個傳輸輪次所需時間為一個往返時間 RTT,但 ** 傳輸輪次強調的是將一個 cwnd 窗口中所允許發送的報文段全都發送出去并且都接收到對應于最后一個報文段的確認報文 ** 。
慢開始中的“慢”并非指傳輸速率很慢,而是說開始的時候將 cwnd 設為 1,使得發送方最開始只能發送一個報文段(目的在于試探當前網絡的擁塞狀況),然后再 ** 指數增長 ** cwnd 的大小。
** 慢開始門限值 ssthresh ** :因為慢開始算法以指數型式增長,所以為了防止后期因為cwnd 窗口增長過快而導致網絡出現擁塞,需要設置一個慢開始的門限值,當 cwnd 增長至門限值大小時,停止采用慢開始算法而改用擁塞避免算法。
? 當 cwnd < ssthresh 時,使用慢開始算法;
? 當 cwnd > ssthresh 時,停止使用慢開始算法而改用擁塞避免算法;
? 當 cwnd = ssthresh 時,既可使用慢開始算法,也可使用擁塞控制避免算法。
擁塞避免
讓擁塞窗口以 ** 線性增長 ** 的方式緩慢增大,從而減少注入到網絡中的數據,以盡量避免網絡擁塞。具體而言,每經過一個傳輸輪次才將發送方的 cwnd+1,而非每接收到一個確認報文就加 1,這樣的話,每經過一個傳輸輪次,擁塞窗口才增長了 1 個 MSS,而非加倍,cwnd 呈線性增長而非指數增長,由此可知,擁塞避免算法的 cwnd 增長速率比慢開始算法慢很多。
“擁塞避免”并非指完全能夠避免了擁塞。利用以上的措施要完全避免網絡擁塞還是不可能的。“擁塞避免”是說在擁塞避免階段將擁塞窗口控制為按線性規律增長,使網絡比較不容易出現擁塞。
** 注意 ** :無論在慢開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(根據就是沒有收到確認),就要把慢開始門限 ssthresh 設置為出現擁塞時的發送方窗口值的一半(但不能小于 2)。然后把擁塞窗口 cwnd 重新設置為 1,執行慢開始算法。這樣做的目的就是要迅速減少主機發送到網絡中的分組數,使得發生擁塞的路由器有足夠時間把隊列中積壓的分組處理完畢。
快重傳
快重傳算法首先要求接收方每收到一個失序的報文段后就 ** 立即 ** 發出重復確認(為的是使發送方及早知道有報文段沒有到達對方)而不要等到自己發送數據時才進行捎帶確認。快重傳算法還規定,發送方只要一連收到 ** 三個重復確認 ** 就應當立即重傳對方尚未收到的報文段,而不必繼續等待設置的重傳計時器到期。由于發送方盡早重傳未被確認的報文段,因此采用快重傳后可以使整個網絡吞吐量提高。
快恢復
當發送方連續收到三個重復確認,就執行“乘法減小”算法,把慢開始門限 ssthresh ** 減半 ** 。這是為了預防網絡發生擁塞。由于發送方現在認為網絡很可能沒有發生擁塞,因此與慢開始不同之處在于現在 ** 不執行慢開始算法 ** (即擁塞窗口 cwnd 現在不設置為 1),而是把 cwnd 值設置為慢開始門限 ssthresh 減半后的數值,然后開始執行 ** 擁塞避免算法 ** (“加法增大”),使擁塞窗口緩慢地線性增大。
基于上述四個算法的擁塞避免流程:
TCP 連接建立后,將發送方 cwnd 設為 1(MSS),并設置慢開始門限值 ssthresh,執行慢開始算法指數增長 cwnd。當 cwnd 達到 ssthresh 時改用擁塞避免算法線性增長 cwnd。如果在數據傳輸過程中出現超時還未收到確認報文的情況,意味著有可能出現網絡擁塞,將ssthresh 設為該時刻的 cwnd 的一半,cwnd 設為 1,重新執行慢開始算法。如果在數據傳輸過程中接收方收到失序的報文段,就采用快重傳算法立即發送重復的確認報文,發送方接收到 3 個相同的確認報文后,意味著有報文丟失,就采用快恢復算法將 ssthresh 和 cwnd 均設為出現擁塞時的cwnd的一半,重新執行擁塞避免算法。轉換圖如下:(圖片來源:TCP的流量控制和擁塞控制)
總結
在采用快恢復算法時,慢開始算法只是在 TCP 連接建立時和網絡出現超時時才使用。采用這樣的擁塞控制方法使得 TCP 的性能有明顯的改進。
接收方根據自己的接收能力設定了接收窗口 rwnd,并把這個窗口值寫入 TCP 首部中的窗口字段,傳送給發送方,接收窗口又稱為 ** 通知窗口 ** 。因此,從接收方對發送方的流量控制的角度考慮,發送方的發送窗口一定不能超過對方給出的接收窗口 rwnd 。所以 ** 發送方窗口的上限值 = Min [ rwnd, cwnd ] :**
? 當rwnd < cwnd 時,是接收方的接收能力限制發送方窗口的最大值;
? 當cwnd < rwnd 時,則是網絡的擁塞限制發送方窗口的最大值。