TCP 怎麼實現擁塞控制?
阿新 • • 發佈:2022-04-18
擁塞控制是作用於網路的,防止過多的資料包注入到網路中,避免出現網路負載過大的情況。它的目標主要是最大化利用網路上瓶頸鍊路的頻寬。
實際上,擁塞控制主要有這幾種常用演算法
- 慢啟動
- 擁塞避免
- 擁塞發生
- 快速恢復
慢啟動演算法
慢啟動演算法,表面意思就是,別急慢慢來。它表示TCP建立連線完成後,一開始不要傳送大量的資料,而是先探測一下網路的擁塞程度。由小到大逐漸增加擁塞視窗的大小,如果沒有出現丟包,每收到一個ACK,就將擁塞視窗cwnd大小就加1(單位是MSS)。每輪次傳送視窗增加一倍,呈指數增長,如果出現丟包,擁塞視窗就減半,進入擁塞避免階段。
- TCP連線完成,初始化cwnd = 1,表明可以傳一個MSS單位大小的資料。
- 每當收到一個ACK,cwnd就加一;
- 每當過了一個RTT,cwnd就增加一倍; 呈指數讓升
為了防止cwnd增長過大引起網路擁塞,還需設定一個慢啟動閥值ssthresh(slow start threshold)狀態變數。當cwnd
到達該閥值後,就好像水管被關小了水龍頭一樣,減少擁塞狀態。即當cwnd >ssthresh時,進入了擁塞避免演算法。
擁塞避免演算法
一般來說,慢啟動閥值ssthresh是65535位元組,cwnd
到達慢啟動閥值後
- 每收到一個ACK時,cwnd = cwnd + 1/cwnd
- 當每過一個RTT時,cwnd = cwnd + 1
顯然這是一個線性上升的演算法,避免過快導致網路擁塞問題。
擁塞發生
當網路擁塞發生丟包時,會有兩種情況:
- RTO超時重傳
- 快速重傳
如果是發生了RTO超時重傳,就會使用擁塞發生演算法
- 慢啟動閥值sshthresh = cwnd /2
- cwnd 重置為 1
- 進入新的慢啟動過程
這真的是辛辛苦苦幾十年,一朝回到解放前。其實還有更好的處理方式,就是快速重傳。傳送方收到3個連續重複的ACK時,就會快速地重傳,不必等待RTO超時再重傳。
慢啟動閥值ssthresh 和 cwnd 變化如下:
- 擁塞視窗大小 cwnd = cwnd/2
- 慢啟動閥值 ssthresh = cwnd
- 進入快速恢復演算法
快速恢復
快速重傳和快速恢復演算法一般同時使用。快速恢復演算法認為,還有3個重複ACK收到,說明網路也沒那麼糟糕,所以沒有必要像RTO超時那麼強烈。
正如前面所說,進入快速恢復之前,cwnd 和 sshthresh已被更新:
然後,真正的快速演算法如下:
- cwnd = sshthresh + 3
- 重傳重複的那幾個ACK(即丟失的那幾個資料包)
- 如果再收到重複的 ACK,那麼 cwnd = cwnd +1
- 如果收到新資料的 ACK 後, cwnd = sshthresh。因為收到新資料的 ACK,表明恢復過程已經結束,可以再次進入了擁塞避免的演算法了。
-