# TCP Congestion Control - Introduction [TOC] ## 課程影片 ### 第 8H 講 TCP 與網路阻塞偵測與控制技術 L08 8 {%youtube 1tVlihcMMF8 %} ### How TCP Works - Bytes in Flight {%youtube 9lJ0vsA40is %} ## 幾種 Window TCP 傳送時,必須要知道自己可以傳送多少東西才不會造成網路壅塞。就算現在網路很壅塞,也要知道網路正在壅塞,並且自己調整。 ### 定義:Advertised Window *Advertised window* 指得是「接收方在一個 RTT 內,最多能接收多少位元組資料?」。這個也就是 TCP 封包中的 `window` 欄位。這個在前面 TCP 封包格式時就介紹過了。 ### 定義:Congestion Window 「網路在一個 RTT 內,最多允許多少位元組的資料通過?」,這邊稱為 *congestion window*。既然 *congestion window* 表示「一個 RTT 的時間內,最多可以傳送多少位元組的資料?」因此,把 *congestion window* 除掉 RTT 的時間,就會是「平均一秒能傳輸多少位元組的資料?」。這個數值稱為網路的 *transmission rate*。即: $$ r_\text{transmit} = \frac {\text{Congestion Window (byte)}}{\text{RTT (s)}} $$ ### 定義:Max Window 在考慮該用多大的流量傳輸時,必須同時考慮在傳送的時候,應取這兩個數值的最小值。比如說:如果網路很壅塞,那麼就算接收方的 *buffer* 再大,流量也無法增加。反之,若網路很順暢,但接收方一次能接收的資料很少,那麼也不能以太大的流量傳送。因此,實際上一個 RTT 內可以傳輸的最大數量的資料,是兩者的最小值。這個值稱為 *Max Window*: $$ \text{MaxWin} = \min (\text{ConWin}, \text{AdvWin}) $$ ### 定義:Effective Window 這個 *max window* 中,是一個 RTT 內可以向發送方傳輸的最大位元組數目。不過,如果在這個 RTT 內已經傳輸了某些數目的資料,那麼剩餘的額度就會變少。這個「一個 RTT 內可以傳輸資料的剩餘額度」稱為 *effective window*,也就是: $$ \begin{align} \text{EffWindow} = &\text{MaxWindow} \newline &- (\text{LastByteSent} - \text{LastByteAck}) \end{align} $$ 其中,`LastByteSent` 是最後一個送出去的位元組的流水號,而 `LastByteAck` 則是最後一個收到 ACK 的位元組的流水號。所以兩者相減,就會得到還在途中的位元組數目。 ## 核心問題:如何決定 Congeston Window? 在上述的幾個 *window* 中,*advertised window* 是是由發送方傳送的封包中決定的,因此上述的四種大小中,就只有 *congestion window* 是未知的。而這個值必須由==發送方自己想辦法估計==。不過,大致上的原則是: 1. 發現網路變得壅塞時,就把 *congestion window* 降低。 2. 發現壅塞比較不壅塞,就把 *congestion* 增加。 那 TCP 要怎麼知道「網路變得壅塞」呢?答案是:透過收到 ACK 的步調。如果 ACK 有少、有重複,或是逾時,就可以知道網路現在比自己想像中的壅塞,因此就需要去調整自己傳送的速度。換句話說,TCP 可以透過收到的 ACK 自我調整傳輸速度。因此,有時候也會說:TCP 使用 ACK 來 *self-clocking*。 接下來要介紹兩個估計方法:*AIMD* 與 *Slow Start*。