1. 程式人生 > >TCP擁塞控制機制(附面試題)

TCP擁塞控制機制(附面試題)

產生的原因

>

注意
單純的增加網路資源無法解決問題
例如:把結點的儲存空間擴大,更換更高速率的鏈路,提高結點處理機的運算速度,不僅不能解決問題,而且可能使網路效能更壞。
原因:網路擁塞是許多因素引起的,單純的解決一個可能會使上述情況得到一些緩解,但是會把擁塞轉移到其他地方。
擴大結點儲存空間——>由於輸出鏈路的容量和處理機的速度並未提高,增大排隊等待時間,超時重傳,浪費資源。
更換更高速率的鏈路——>可能會緩解,,有可能造成各部分不匹配。

擁塞控制的作用

擁塞控制的作用

注意
擁塞控制與流量控制的區別
擁塞控制是防止過多的資料注入到網路中,可以使網路中的路由器或鏈路不致過載,是一個全域性性的過程。
流量控制是點對點通訊量的控制,是一個端到端的問題,主要就是抑制傳送端傳送資料的速率,以便接收端來得及接收。

擁塞的標誌

1.重傳計時器超時
2.接收到三個重複確認

擁塞控制的機制

TCP擁塞控制流程圖
從連續收到三個重複的    確認轉入擁塞避免

慢開始與擁塞避免

慢開始

1.慢開始不是指cwnd的增長速度慢(指數增長),而是指TCP開始傳送設定cwnd=1。
2.思路:不要一開始就傳送大量的資料,先探測一下網路的擁塞程度,也就是說由小到大逐漸增加擁塞視窗的大小。這裡用報文段的個數的擁塞視窗大小舉例說明慢開始演算法,實時擁塞視窗大小是以位元組為單位的。如下圖:
每經過一個傳輸輪次,cnwd指數增長
3.為了防止cwnd增長過大引起網路擁塞,設定一個慢開始門限(ssthresh狀態變數)
當cnwd<ssthresh,使用慢開始演算法
當cnwd=ssthresh,既可使用慢開始演算法,也可以使用擁塞避免演算法
當cnwd>ssthresh,使用擁塞避免演算法

擁塞避免(按線性規律增長)

1.擁塞避免並非完全能夠避免擁塞,是說在擁塞避免階段將擁塞視窗控制為按線性規律增長,使網路比較不容易出現擁塞。
2.思路:讓擁塞視窗cwnd緩慢地增大,即每經過一個往返時間RTT就把傳送方的擁塞控制視窗加一。


無論是在慢開始階段還是在擁塞避免階段,只要傳送方判斷網路出現擁塞(其根據就是沒有收到確認,雖然沒有收到確認可能是其他原因的分組丟失,但是因為無法判定,所以都當做擁塞來處理),就把慢開始門限設定為出現擁塞時的傳送視窗大小的一半。然後把擁塞視窗設定為1,執行慢開始演算法。
慢開始與擁塞避免演算法的實現

加法增大與乘法減小
乘法減小:無論是慢開始階段還是擁塞避免,只要出現了網路擁塞(超時),就把慢開始門限值ssthresh減半
加法增大:執行擁塞避免演算法後,擁塞視窗線性緩慢增大,防止網路過早出現擁塞

快重傳與快恢復

增加快重傳與快恢復

快重傳

1.快重傳要求接收方在收到一個失序的報文段後就立即發出重複確認(為的是使傳送方及早知道有報文段沒有到達對方)而不要等到自己傳送資料時捎帶確認。快重傳演算法規定,傳送方只要一連收到三個重複確認就應當立即重傳對方尚未收到的報文段,而不必繼續等待設定的重傳計時器時間到期。
快重傳示意圖
2.由於不需要等待設定的重傳計時器到期,能儘早重傳未被確認的報文段,能提高整個網路的吞吐量。

快恢復(與快重傳配合使用)

1.採用快恢復演算法時,慢開始只在TCP連線建立時和網路出現超時時才使用。
2.當傳送方連續收到三個重複確認時,就執行“乘法減小”演算法,把ssthresh門限減半。但是接下去並不執行慢開始演算法。
3.考慮到如果網路出現擁塞的話就不會收到好幾個重複的確認,所以傳送方現在認為網路可能沒有出現擁塞。所以此時不執行慢開始演算法,而是將cwnd設定為ssthresh的大小,然後執行擁塞避免演算法。

注意
傳送方視窗的上限值=Min(接受視窗rwnd,擁塞視窗cwnd)
rwnd>cwnd 接收方的接收能力限制傳送方視窗的最大值
rwnd<cwnd 網路的擁塞限制傳送方視窗的最大值

面試題

騰訊面試題
TCP的擁塞控制機制是什麼?請簡單說說。
答:我們知道TCP通過一個定時器(timer)取樣了RTT並計算RTO,但是,如果網路上的延時突然增加,那麼,TCP對這個事做出的應對只有重傳資料,然而重傳會導致網路的負擔更重,於是會導致更大的延遲以及更多的丟包,這就導致了惡性迴圈,最終形成“網路風暴” —— TCP的擁塞控制機制就是用於應對這種情況。
首先需要了解一個概念,為了在傳送端調節所要傳送的資料量,定義了一個“擁塞視窗”(Congestion Window),在傳送資料時,將擁塞視窗的大小與接收端ack的視窗大小做比較,取較小者作為傳送資料量的上限。
擁塞控制主要是四個演算法:
1.慢啟動:意思是剛剛加入網路的連線,一點一點地提速,不要一上來就把路佔滿。
連線建好的開始先初始化cwnd = 1,表明可以傳一個MSS大小的資料。
每當收到一個ACK,cwnd++; 呈線性上升
每當過了一個RTT,cwnd = cwnd*2; 呈指數讓升
閾值ssthresh(slow start threshold),是一個上限,當cwnd >= ssthresh時,就會進入“擁塞避免演算法”
2.擁塞避免:當擁塞視窗 cwnd 達到一個閾值時,視窗大小不再呈指數上升,而是以線性上升,避免增長過快導致網路擁塞。
每當收到一個ACK,cwnd = cwnd + 1/cwnd
每當過了一個RTT,cwnd = cwnd + 1
擁塞發生:當發生丟包進行資料包重傳時,表示網路已經擁塞。分兩種情況進行處理:
等到RTO超時,重傳資料包
sshthresh = cwnd /2
cwnd 重置為 1
3.進入慢啟動過程
在收到3個duplicate ACK時就開啟重傳,而不用等到RTO超時
sshthresh = cwnd = cwnd /2
進入快速恢復演算法——Fast Recovery
4.快速恢復:至少收到了3個Duplicated Acks,說明網路也不那麼糟糕,可以快速恢復。
cwnd = sshthresh + 3 * MSS (3的意思是確認有3個數據包被收到了)
重傳Duplicated ACKs指定的資料包
如果再收到 duplicated Acks,那麼cwnd = cwnd +1
如果收到了新的Ack,那麼,cwnd = sshthresh ,然後就進入了擁塞避免的演算法了。