該文轉載:https://www.colabug.com/2018/0916/4545167/
侵權立刪!!
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
超時觸發重傳存在的一個問題就是超時周期過長。因此,發送方通??稍诔瑫r事件發生之前通過所謂的冗余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減半后的數值,然后執行擁塞避免算法,使擁塞窗口緩慢線性增大。
實現過程如下圖所示: