1. 程式人生 > 其它 >TCP 怎麼實現擁塞控制?

TCP 怎麼實現擁塞控制?

擁塞控制是作用於網路的,防止過多的資料包注入到網路中,避免出現網路負載過大的情況。它的目標主要是最大化利用網路上瓶頸鍊路的頻寬。

實際上,擁塞控制主要有這幾種常用演算法

  • 慢啟動
  • 擁塞避免
  • 擁塞發生
  • 快速恢復

慢啟動演算法

慢啟動演算法,表面意思就是,別急慢慢來。它表示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,表明恢復過程已經結束,可以再次進入了擁塞避免的演算法了。
  •  
  •