快速了解TCP的流量控制與擁塞控制


有關TCP你不能不知道的三次握手和四次揮手問題,點我跳轉

流量控制

1. 滑動窗口

數據的傳送過程中很可能出現接收方來不及接收的情況,這時就需要對發送方進行控制以免數據丟失。利用滑動窗口機制可以很方便地在TCP連接上對發送方的流量進行控制。TCP的窗口單位是字節,不是報文段,發送方的發送窗口不能超過接收方給出的接收窗口的數值。

TCP滑動窗口

TCP規定,即使設置為零窗口,也必須接收以下幾種報文段:

  • 零窗口探測報文段
  • 確認報文段
  • 攜帶緊急數據的報文段

確認丟失和確認遲到

確認丟失和確認遲到

持續計時器

存在這樣一種情況:發送方接收到零窗口報文之后將發送窗口設置為0,停止發送數據。但等到接收方有足夠緩存,發送了非零窗口大小的報文,但是這個報文中途丟失,那么發送方的發送窗口就一直為0導致死鎖。
為此,TCP為每一個連接設有一個持續計時器(Persistence Timer):當TCP連接的一方收到對方的零窗口通知時就啟動持續計時器。若持續計時器時間到期,就發送一個零窗口探測報文段(攜有1字節的數據),那么收到這個報文段的一方就在確認這個探測報文段時給出了現在的窗口值。若窗口仍然是零,則收到這個報文段的一方就重新設置持續計時器;若窗口不是零,則死鎖的僵局就可以打破了。

2. 延遲ACK

如果TCP對每個數據包都發送一個ACK確認,那么只是一個單獨的數據包為了發送一個ACK代價比較高,所以TCP會延遲一段時間,如果這段時間內有數據發送到對端,則捎帶發送ACK,如果在延遲ACK定時器觸發時候,發現ACK尚未發送,則立即單獨發送;

延遲ACK好處:

  1. 避免糊塗窗口綜合症。
  2. 發送數據的時候將ACK捎帶發送,不必單獨發送ACK。如果延遲時間內有多個數據段到達,那么允許協議棧發送一個ACK確認多個報文段。減少流量消耗。

糊塗窗口綜合症:TCP接收方的緩存已滿,而交互式的應用進程一次只從接收緩存中讀取1字節(這樣就使接收緩存空間僅騰出1字節),然后向發送方發送確認,並把窗口設置為1個字節(但發送的數據報為40字節的的話)。當發送方又發來1個字節的數據(發送方的IP數據報是41字節),接收方發回確認,仍然將窗口設置為1個字節。這樣,網絡的效率很低。要解決這個問題,可讓接收方等待一段時間,使得或者接收緩存已有足夠空間容納一個最長的報文段或者等到接收方緩存已有一半的空閑空間。只要出現這兩種情況,接收方就發回確認報文,並向發送方通知當前的窗口大小。此外,發送方也不要發送太小的報文段,而是把數據報積累成足夠大的報文段,或達到接收方緩存的空間的一半大小。

擁塞控制

擁塞控制與流量控制的區別 :
擁塞控制是防止過多的數據注入到網絡中,可以使網絡中的路由器或鏈路不致過載,是一個全局性的過程。
流量控制是點對點通信量的控制,是一個端到端的問題,主要就是抑制發送端發送數據的速率,以便接收端來得及接收。

擁塞控制的作用

擁塞控制是為了防止過多的數據注入到網絡中,這樣可以使網絡中的路由器或者鏈路不至於過載。

擁塞控制的作用

擁塞控制的算法

我們假定:

  1. 數據單方向傳送,而另外一個方向只傳送確認。
  2. 接收方總是有足夠大的緩存空間,因為發送窗口的大小由網絡的擁塞程度來決定。

發送方的發送窗口的上限值應當取為接收方窗口rwnd和擁塞窗口cwnd這兩個變量中較小的一個,即發送窗口的上限值為Min[rwnd, cwnd]

當rwnd < cwnd時,是接收方的接收能力限制發送窗口的最大值
當cwnd < rwnd時,則是網絡的擁塞限制發送窗口的最大值

擁塞控制的過程一共涉及了4種算法:

  1. 慢啟動
  2. 擁塞避免
  3. 快重傳
  4. 快恢復

1. 慢啟動

發送方維護一個擁塞窗口cwnd的狀態變量,擁塞窗口的大小取決於網絡的擁塞程度,動態變化。通過逐漸增加cwnd的大小來探測可用的網絡容量,防止連接開始時采用不合適的發送量導致網絡擁塞。

當主機開始發送數據時,如果通過較大的發送窗口立即將全部數據字節都注入到網絡中,由於不清楚網絡狀況,有可能引起網絡擁塞。較好的方法是試探,從小到大逐漸增大發送端擁塞窗口的cwnd數值。

例如:開始發送方先設置cwnd=1,發送第一個報文段M1,接收方接收到M1后,ACK返回給發送端,發送端將cwnd增加到2,接着發送方發送M2,再次接受到ACK后將cwnd增加到4...慢啟動算法每經過一個傳輸輪次,擁塞窗口cwnd就加倍。

當rwnd足夠大時,為防止擁塞窗口cwind的增長引起網絡擁塞,還需要另外一個變量,慢開始門限ssthresh

當cwnd<ssthresh,使用慢開始算法
當cwnd=ssthresh,既可使用慢開始算法,也可以使用擁塞避免算法
當cwnd>ssthresh,使用擁塞避免算法

首次慢啟動的ssthresh值,可以參閱網上的各種討論,限於篇幅,本文不作介紹~

2.擁塞避免

TCP擁塞控制

控制過程:

  1. TCP連接初始化,將擁塞窗口cwnd設置為1個報文段,即cwnd=1
  2. 執行慢開始算法,cwnd按指數規律增長,直到cwnd == ssthresh時,開始擁塞避免算法,cwnd按線性規律增長
  3. 當網絡發生阻塞,把ssthresh值更新為擁塞前cwnd的一半(12=24/2),cwnd重新設置為1,再按照(2)執行

讓擁塞窗口cwnd緩慢地增大,每經過一個往返時間RTT就把發送方的擁塞窗口cwnd+1,而不是加倍。這樣擁塞窗口cwnd線性緩慢增長,比慢開始算法的擁塞窗口增長速率緩慢地多。

無論慢啟動開始階段還是在擁塞避免階段,只要發送方判斷網絡出現擁塞(沒收到ACK),就把慢啟動門限ssthresh設置為出現擁塞時的cwnd的一半。然后把擁塞窗口cwnd重新設置為1,執行慢啟動算法。這樣做的目的是能迅速的減少主機向網絡中傳輸數據,使發生擁塞的路由器能夠把隊列中堆積的分組處理完畢。擁塞窗口是按照線性的規律增長,比慢啟動算法擁塞窗口增長快的多。

擁塞避免是由指數增長拉低到線性增長,降低出現擁塞的可能,並不是能完全避免網絡擁塞

3.快重傳

一條TCP連接有時會因等待重傳計時器的超時而空閑較長的時間,慢開始和擁塞避免無法很好地解決這類問題,因此提出了快重傳和快恢復的擁塞控制方法。

為使發送方及早知道有報文沒有達到對方,快重傳算法首先要求接受方每收到一個報文段后就立即發出重復確認。快重傳算法並非取消了重傳機制,只是在某些情況下更早地重傳丟失的報文段。即,當TCP源端收到3個相同的ACK確認時,即認為有數據包丟失,則源端重傳丟失的數據包,而不必等待RTO(Retransmission Timeout)超時。由於發送方盡早重傳未被確認的報文段。因此,采用快重傳后可以使整個網絡吞吐量提高20%

TCP快重傳

快重傳算法要求首先接收方收到一個失序的報文段后就立刻發出重復確認,而不要等待自己發送數據時才進行捎帶確認。接收方成功的接受了發送方發送來的M1、M2並且分別給發送了ACK,現在接收方沒有收到M3,而接收到了M4,顯然接收方不能確認M4,因為M4是失序的報文段。如果根據可靠性傳輸原理接收方什么都不做,但是按照快速重傳算法,在收到M4、M5等報文段的時候,不斷重復的向發送方發送M2的ACK,如果接收方一連收到三個重復的ACK,那么發送方不必等待重傳計時器到期,由於發送方盡早重傳未被確認的報文段。

4.快恢復

TCP快恢復

快恢復算法控制過程:
當發送方連續收到3個重復確認時,發送方認為網絡很可能沒有發生擁塞,因此不執行慢啟動。而是把cwnd值設為新的門限值,然后執行擁塞避免算法,cwnd值線性增大,避免了當網絡擁塞不夠嚴重時采用"慢啟動"算法而造成過大地減小發送窗口尺寸的現象,這就是快恢復。

最后,限於筆者經驗水平有限,歡迎讀者就文中的觀點提出寶貴的建議和意見。如果想獲得更多的學習資源或者想和更多的是技術愛好者一起交流,可以關注我的公眾號『全菜工程師小輝』后台回復關鍵詞領取學習資料、進入前后端技術交流群和程序員副業群。同時也可以加入程序員副業群Q群:735764906 一起交流。

哎呀,如果我的名片丟了。微信搜索“全菜工程師小輝”,依然可以找到我


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM