TCP流量控制和擁塞控制機制
簡單列一些比較常用的欄位意義,方便後面對TCP建立,重傳機制的理解:
- 序號欄位(sequence number):因為TCP是面向位元組流的,所以TCP連線中傳送的資料流中每個位元組都編上序號。序號欄位指的是本報文所傳送資料的第一個位元組的序號
- 確認號欄位(acknoledgement number):期望收到對方的下一個報文段的資料的第一個位元組的序號,若確認號=N,則表明到序號N-1為止的所有資料都已正確收到
- 確認位ACK: 當ACK=1時確認號欄位為有效,當ACK=0為無效
- 同步位SYN:同步SYN=1表示這是一個連線請求或連線接收報文
- 終止位FIN:用來釋放一個連線,FIN=1表明此報文段的傳送方的資料已傳送完畢,並要求釋放傳輸連線
- 視窗欄位:支出現在允許對方傳送的資料量。如確認號是701,視窗欄位是1000,表明從701號算起,傳送此報文段的一方還有接收1000位元組資料(位元組序號是701-1700)的接收快取空間
TCP連線管理
TCP是面向連線的協議,每一個TCP連線都會經過三個階段:連線建立、資料傳送和連線釋放。TCP連線的兩個埠叫做套接字或插口,連線的建立採用客戶/伺服器方式,主動傳送連線建立的應用程序叫做客戶機(client),而被動等待連線建立的應用程式叫做伺服器(server)。
TCP連線三次握手
- 客戶機首先向伺服器的TCP傳送SYN=1,表示一個連線請求報文段,隨機選擇一個起始序號seq=x
- 伺服器的TCP收到連線請求報文段,如果同意建立連線,就像客戶機發回確認ACK=1,併為該TCP連線分配TCP快取和變數,並隨機產生起始序號seq=y
- 當客戶機收到確認報文後,還要想伺服器給出確認,並且也要給連線分配快取和變數
注意:服務端資源是在完成第二次握手分配的,而客戶端資源是在完成第三次握手分配的,使得伺服器易於收到SYN洪泛攻擊
TCP連線的釋放
- 客戶機打算關閉連線,向TCP傳送FIN=1標誌位的連線釋放報文段,並停止再發送資料,seq=u等於前面已傳送過的資料的最後一個位元組的序號加1
- 伺服器疏導釋放報文段,發出確認號ack=u+1。此時,從客戶機到伺服器這個方向的連線就釋放了,TCP連線處於半關閉狀態。但伺服器若傳送資料,客戶機仍要接收,即從伺服器到客戶機這個方向的連線並未關閉
- 若伺服器已經沒有向客戶機發送的資料,就通知TCP釋放連線,此時傳送FIN=1的連線釋放報文段
- 客戶機收到連線釋放報文段後,必須發出確認,ACK=1, 確認好ack=w+1,序號seq=u+1。此時TCP連線還沒有釋放掉,必須經過時間等待計時器設定的時間2MSL後,A才進入到連線關閉狀態
重傳機制
導致TCP對報文進行重傳的兩種情況:超時和冗餘ACK
- 超時
TCP每傳送一個報文段,就對這個報文段設定一次計時器,只要計時器設定的重傳時間到期還沒有收到確認,就要重傳這一報文段。而重傳時間的計算採用了一種自適應演算法,略大於加權平均往返時間RTTs,RTTs指的是一個報文段發出的時間到收到確認的時間之間的時間。 - 冗餘ACK
超時觸發重傳存在的一個問題就是超時週期過長。因此,傳送方通常可在超時事件發生之前通過所謂的冗餘ACK來較好的檢測丟包情況。TCP規定當傳送方收到對同一個報文段的3個冗餘ACK時,就可以認為該報文段已經丟失。
舉個栗子:
傳送方A傳送了序號為1,2,3,4,5的TCP報文段,其中2號報文在鏈路中丟失,無法到達接收方B,因此3,4,5對B來說是失序報文段。TCP規定當期望序號大的失序報文段到達時,傳送一個冗餘ACK,指明下一個期待位元組的序號。因此,當3,4,5報文到達B,並不是B期望收到的下一個報文,於是B就傳送3個1號報文段的冗餘ACK,表示自己期望接收2號報文段。這時A收到3個冗餘ACK就判斷2號報文段已經丟失,這時傳送方A可以立即對2號報文執行重傳。這種技術通常稱為快速重傳。
TCP流量控制
TCP流量控制服務以消除傳送方使接收方快取區溢位的可能性,也就是說流量控制是一個速度匹配服務(匹配發送方的傳送速率和接收方的讀取速率)。
原理:
TCP使用視窗機制來實現流量控制的。原理是:在通訊過程中,接收方根據自己接收快取的大小,動態調整發送方的傳送視窗大小,即TCP報文段首部中的“視窗”欄位rwnd,來限制傳送方向網路注入報文的速率。同時,傳送方根據其對當前網路擁塞程式的估計確定一個擁塞視窗cwnd,最終A傳送的視窗的實際大小是min(rwnd,cwnd)值。
下圖是主機A向主機B傳送資料,在連線建立時,B告訴A”我的接收視窗rwnd=400(位元組)”

TCP擁塞控制
所謂擁塞控制就是防止過多的資料注入網路中,這樣可以使網路中的路由器或鏈路不致過載。擁塞控制和流量控制都是太那個個控制傳送方傳送資料的速率來達到效果的。
區別在於:擁塞控制是讓網路能夠承受現有的網路負荷,它是一個全域性性的過程,設計所有主機,路由器以及網路傳輸效能有關的所有因素。而流量控制往往是指點對點的通訊量的控制,即接收端控制傳送端,即抑制傳送端傳送資料的速率,以便使接收端來得及接收。
因此,傳送方在確定傳送報文段的速率時,既要根據接收方的接收能力,又要從全域性考慮不要使網路傳送擁塞,因此,TCP協議要求傳送方維護兩個視窗:
- 接收視窗rwnd,接收方根據目前接收快取大小所設定的視窗值
- 擁塞視窗cwnd,傳送方根據自己估算的網路擁塞程度設定的視窗值,反映了網路的當前容量。
傳送視窗的上限取得是接收視窗rwnd和擁塞視窗cwnd中較小的一個,即min(rwnd,cwnd)
接受視窗根據TCP報文首部的視窗欄位確定,擁塞視窗怎麼維護呢?為了更好地對傳輸層進行擁塞控制,給出了下面四種演算法:慢開始、擁塞避免、快重傳、快恢復
擁塞控制演算法
慢開始演算法
在TCP剛連線好,開始傳送TCP報文段時,先令擁塞視窗cwnd=1,在每收到一個對新的報文段確認後,再將cwnd加1,慢開始演算法,每經過一個傳輸輪次(即往返RTT),擁塞視窗cwnd就會加倍,即呈指數形式增加,當慢開始演算法把擁塞視窗cwnd增大到一個閾值ssthresh,改用擁塞避免演算法。
擁塞避免演算法
擁塞避免演算法的做法是:傳送端的擁塞視窗cwnd每經過一個往返RTT,按線性規律緩慢增長。
網路擁塞的處理
當網路出現擁塞,不管是在慢開始階段還是擁塞避免階段,只要傳送方檢測到超時事件傳送,就要把慢開始閾值ssthresh設定為出現擁塞時的傳送方cwnd的一半(但不能小於2),然後將擁塞視窗cwnd重新設定為1,執行慢開始演算法。這樣做的目的是迅速減少主機發送到網路中的分組數,使得傳送擁塞的路由器有足夠的時間把佇列中積壓的分組處理完畢。
慢開始和擁塞避免演算法實現過程如圖所示:

注意:在慢開始階段,若2 cwnd>ssthresh,則下一個RTT的cwnd應等於ssthresh,而不是2 cwnd,即cwnd不能超過ssthresh值
快重傳和快恢復
快重傳和快恢復演算法是對慢開始和擁塞避免演算法的改進
- 快重傳
當傳送方連續收到三個重複的ACK報文,直接重傳對方尚未收到的報文段,而不必等待那個報文段設定的重傳計時器超時。 - 快恢復
當傳送端收到連續三個冗餘ACK時,就執行“乘法減少”演算法,把慢開始閾值ssthresh設定為出現擁塞時傳送方cwnd的一半。與慢開始將擁塞視窗cwnd設定為1的不同之處,它把cwnd的值設定為慢開始閾值ssthresh減半後的數值,然後執行擁塞避免演算法,使擁塞視窗緩慢線性增大。
實現過程如下圖所示:
