TCP基礎 —— 流量控制與擁塞控制
一:流量控制
什麼是流量控制?流量控制的目的?
如果傳送者傳送資料過快,接收者來不及接收,那麼就會有分組丟失。為了避免分組丟失,控制傳送者的傳送速度,使得接收者來得及接收,這就是流量控制。流量控制根本目的是防止分組丟失,它是構成TCP可靠性的一方面。
如何實現流量控制?
由滑動視窗協議(連續ARQ協議)實現。滑動視窗協議既保證了分組無差錯、有序接收,也實現了流量控制。主要的方式就是接收方返回的 ACK 中會包含自己的接收視窗的大小,並且利用大小來控制傳送方的資料傳送。
流量控制引發的死鎖?怎麼避免死鎖的發生?
當傳送者收到了一個視窗為0的應答,傳送者便停止傳送,等待接收者的下一個應答。但是如果這個視窗不為0的應答在傳輸過程丟失,傳送者一直等待下去,而接收者以為傳送者已經收到該應答,等待接收新資料,這樣雙方就相互等待,從而產生死鎖。 為了避免流量控制引發的死鎖,TCP使用了持續計時器。每當傳送者收到一個零視窗的應答後就啟動該計時器。時間一到便主動傳送報文詢問接收者的視窗大小。若接收者仍然返回零視窗,則重置該計時器繼續等待;若視窗不為0,則表示應答報文丟失了,此時重置傳送視窗後開始傳送,這樣就避免了死鎖的產生。
二:擁塞控制和流量控制的區別
擁塞控制:擁塞控制是作用於網路的,它是防止過多的資料注入到網路中,避免出現網路負載過大的情況;常用的方法就是:( 1 )慢開始、擁塞避免( 2 )快重傳、快恢復。
流量控制:流量控制是作用於接收者的,它是控制傳送者的傳送速度從而使接收者來得及接收,防止分組丟失的。
三:擁塞控制的演算法
我們在開始假定:1、資料是單方向傳遞,另一個視窗只發送確認;2、接收方的快取足夠大,因此傳送方的大小的大小由網路的擁塞程度來決定。
(一)慢開始演算法:
傳送方維持一個叫做擁塞視窗cwnd(congestion window)的狀態變數。擁塞視窗的大小取決於網路的擁塞程度,並且動態地在變化。傳送方讓自己的傳送視窗等於擁塞視窗,另外考慮到接受方的接收能力,傳送視窗可能小於擁塞視窗。
慢開始演算法的思路就是,不要一開始就傳送大量的資料,先探測一下網路的擁塞程度,也就是說由小到大逐漸增加擁塞視窗的大小。
這裡用報文段的個數作為擁塞視窗的大小舉例說明慢開始演算法,實際的擁塞視窗大小是以位元組為單位的。如下圖:
從上圖可以看到,一個傳輸輪次所經歷的時間其實就是往返時間RTT,而且沒經過一個傳輸輪次(transmission round),擁塞視窗cwnd就加倍。
為了防止cwnd增長過大引起網路擁塞,還需設定一個慢開始門限ssthresh狀態變數。ssthresh的用法如下:當cwnd<ssthresh時,使用慢開始演算法。 當cwnd>ssthresh時,改用擁塞避免演算法。 當cwnd=ssthresh時,慢開始與擁塞避免演算法任意
注意,這裡的“慢”並不是指cwnd的增長速率慢,而是指在TCP開始傳送報文段時先設定cwnd=1,然後逐漸增大,這當然比按照大的cwnd一下子把許多報文段突然注入到網路中要“慢得多”。
(二)擁塞避免演算法:
擁塞避免演算法讓擁塞視窗緩慢增長,即每經過一個往返時間RTT就把傳送方的擁塞視窗cwnd加1,而不是加倍。這樣擁塞視窗按線性規律緩慢增長。
無論是在慢開始階段還是在擁塞避免階段,只要傳送方判斷網路出現擁塞(其根據就是沒有按時收到確認,雖然沒有收到確認可能是其他原因的分組丟失,但是因為無法判定,所以都當做擁塞來處理),就把慢開始門限ssthresh設定為出現擁塞時的傳送視窗大小的一半(但不能小於2)。然後把擁塞視窗cwnd重新設定為1,執行慢開始演算法。這樣做的目的就是要迅速減少主機發送到網路中的分組數,使得發生擁塞的路由器有足夠時間把佇列中積壓的分組處理完畢。
整個擁塞控制的流程如下圖:
(1)擁塞視窗cwnd初始化為1個報文段,慢開始門限初始值為16 (2)執行慢開始演算法,指數規律增長到第4輪,即cwnd=16=ssthresh,改為執行擁塞避免演算法,擁塞視窗按線性規律增長 (3)假定cwnd=24時,網路出現超時(擁塞),則更新後的ssthresh=12,cwnd重新設定為1,並執行慢開始演算法。當cwnd=12=ssthresh時,改為執行擁塞避免演算法
關於 乘法減小(Multiplicative Decrease)和加法增大(Additive Increase):
“乘法減小”指的是無論是在慢開始階段還是在擁塞避免階段,只要傳送方判斷網路出現擁塞,就把慢開始門限ssthresh設定為出現擁塞時的傳送視窗大小的一半,並執行慢開始演算法,所以當網路頻繁出現擁塞時,ssthresh下降的很快,以大大減少注入到網路中的分組數。“加法增大”是指執行擁塞避免演算法後,使擁塞視窗緩慢增大,以防止過早出現擁塞。常合起來成為AIMD演算法。
注意:“擁塞避免”並非完全能夠避免了阻塞,而是使網路比較不容易出現擁塞。
(三)快重傳演算法:
快重傳要求接收方在收到一個失序的報文段後就立即發出重複確認(為的是使傳送方及早知道有報文段沒有到達對方,可提高網路吞吐量約20%)而不要等到自己傳送資料時捎帶確認。快重傳演算法規定,傳送方只要一連收到三個重複確認就應當立即重傳對方尚未收到的報文段,而不必繼續等待設定的重傳計時器時間到期。如下圖:
(四)快恢復演算法:
快重傳配合使用的還有快恢復演算法,有以下兩個要點:
當傳送方連續收到三個重複確認時,就執行“乘法減小”演算法,把ssthresh門限減半(為了預防網路發生擁塞)。但是接下去並不執行慢開始演算法 考慮到如果網路出現擁塞的話就不會收到好幾個重複的確認,所以傳送方現在認為網路可能沒有出現擁塞。所以此時不執行慢開始演算法,而是將cwnd設定為ssthresh減半後的值,然後執行擁塞避免演算法,使cwnd緩慢增大。如下圖:TCP Reno版本是目前使用最廣泛的版本。
注意:在採用快恢復演算法時,慢開始演算法只是在TCP連線建立時和網路出