Maximum Segment Size,TCP一次傳輸發送的最大數據段長度。

來了解2個TCP的概念:

MSS:Maximum Segment Size,TCP一次傳輸發送的最大數據段長度。

RTT:Round-Trip Time,往返時延,表示從發送端發送數據開始,到發送端收到來自接收端的確認(接收端收到數據後便立即發送確認),總共經歷的時延。

TCP傳輸大塊數據時,肯定需要進行數據分段,而每個分段所能攜帶的最大數據就是1個MSS,假設大塊數據爲100個MSS,那麼發送方發送的方式大概有如下兩種:

1、  每次發送1個,收到接收方確認後,才發送下1個;

2、  一口氣發送100個,然後收到對方一起確認;

顯然,方式1中,一個RTT只能處理一個包,這樣的傳輸效率太低了。而方式2看似很美好,實際會存在兩個問題,一個是接收方的接收窗口未必能一次性接收這麼多數據,另外一個是網絡的帶寬也不一定足夠大,容易出現丟包事故。前一個問題就是標題中的流量控制(Flow control),TCP採用的是滑動窗口機制(Sliding window),後一個問題就是標題中的擁塞控制(Congestion control)。發送方的發送窗口或者說網絡傳輸交互就取決於這兩個問題的控制,誰控制的更嚴格,誰就佔據了決定性因素,這也是爲什麼兩者總是一起出現一起被討論。

流量控制(Flow control):

TCP uses an end-to-end flow control protocol to avoid having the sender send data too fast for the TCP receiver to receive and process it reliably. Having a mechanism for flow control is essential in an environment where machines of diverse network speeds communicate.

TCP使用端到端流量控制協議來避免發送方發送數據太快,以致TCP接收方不能可靠地接收和處理數據。在不同網絡速度的機器進行通信的環境中,具有流量控制機制至關重要。

                                    圖一

圖一爲通過Wireshark抓包192.168.2.1和192.168.2.198的交互截圖,可以看到有個標記Win,這個標記的含義就是接收端告訴發送端自己還有多少緩衝區可以接收數據。於是發送端就可以根據這個接收端的處理能力來發送數據,而不會導致接收端處理不過來。

[TCP zerowindow]& [TCP window Full]

提到Win標記,就順便談一下Wireshark的[TCP zerowindow]和[TCP window Full],當Win=0時,Wireshark就會打上TCP zerowindow,表示緩存區已滿,不能再接收數據了。當Wireshark在一個包上打上TCP window Full,就表示這個包的發送方已經把對方聲明的接收窗口耗盡了。兩者的共同特點都是傳輸暫停,前者的含義是發送方無法再接收數據,後者表示發送方無法再發送數據。

回過頭來再來說滑動窗口。

              圖二截取自《TCP/IP詳解》

                圖三取自參考資料

                 圖四取自參考資料

圖二和圖三可以知道接收方會通知發送方當前已接收到的信息和可用窗口信息。

圖三和圖四可以看出來窗口滑動的過程。

總結:TCP的流量控制由滑動窗口來實現的,滑動窗口控制流量取決於接收方的窗口大小。

 

擁塞控制(Congestion control):

流量控制是端到端的交互,如果只是局域網內的兩臺設備交互,我想通過滑動窗口大概能控制得不差,但是實際網絡的情況非常複雜,發送方和接收方之間還有路由器和交換機,網絡傳輸線路又複雜,這個時候就需要擁塞控制。

擁塞控制主要有四個算法:慢啓動、擁塞避免、快速重傳和快速恢復。

慢啓動:

討論慢啓動算法先來了解下擁塞窗口的概念,這是慢啓動算法爲TCP發送方新增的窗口,congestion window,簡稱cwnd。對應上文,發送方取擁塞窗口和滑動窗口的最小值作爲發送上限,即誰嚴格誰起決定因素。

1、  連接建立開始,發送方不瞭解網絡的情況,cwnd初始化比較小的值,RFC建議2-4個MSS,具體視MSS的大小而定;

If (MSS <= 1095 bytes)

      then win <= 4 * MSS;

If (1095 bytes < MSS < 2190 bytes)

      then win <= 4380;

If (2190 bytes <= MSS)

      then win <= 2 * MSS; 摘自rfc3390.

2、  如果發送出去的包都被ACK,說明還未到達擁塞點,則增加擁塞窗口,RFC建議的是每收到n個ACK,則cwnd新增n個MSS,呈指數關係增長,雖然這個過程看似比較快,但是基數比較低,所以被稱爲“慢啓動”。

擁塞避免:

其實慢啓動除了維護了cwnd,還維護了慢啓動臨界值ssthresh,一般將ssthresh設置爲65535字節。在cwnd<=ssthresh時,還是處於慢啓動環節,一旦>ssthresh,開始進入擁塞避免。

RFC建議擁塞避免環節,無論一個RTT可以收到多少個ACK,每一次確認都只新增1個MSS,呈線性關係增長,避免快速的觸碰到網絡擁塞點。

              圖五取自參考資料

快速重傳和快速恢復:

進入擁塞避免之後,最終還是會碰到擁塞點,發送方此時遲遲得不到確認,當然得不到確認也有可能是因爲延遲確認導致的。發送方此時決定等待一段時間,如果一段時間後還是得不到確認,就發起重傳,這個過程叫做超時重傳。從發出原始包到重傳該包的時間叫做RTO(Retransmission TimeOut)。

進入超時重傳後,RFC建議將cwnd設置爲1個MSS,而對於ssthresh,RFC5681建議的是發生擁塞時未被ACK的數據量的1/2,但必須大於等於2個MSS。然後重新進入慢啓動環節。超時重傳因爲需要等待RTO之後才能進入新的恢復環節,所以對網絡性能的影響是比較大的。所以各路大神又想到了一個新的方式,看能否無需等待RTO,就發起重傳,這種方式叫做快速重傳。快速重傳規定在收到3個及以上重複ACK時就觸發重傳,不再進入慢啓動環節,然後直接進入擁塞避免,這個就是快速恢復算法。爲什麼是3個?因爲1-2個重複ACK,很有可能是亂序,只有在3個及以上的時候纔是有可能丟包了。關於具體快速重傳和快速恢復的算法可以看下參考資料,已經寫得非常詳細了。

 

以上就是我對TCP流量控制和擁塞控制的理解,如有不當言論,歡迎留言交流反饋。

 

參考資料:

https://en.wikipedia.org/wiki/Transmission_Control_Protocol

https://www.douniuyuLept.com /wiki/TCP_congestion_control

https://www.feifanyule.cn /question/32255109

https://www.zhihu.com/question/38749788

https:// www.baohuayule.net /articles/11564.html

https://www.jxbaxi.com/ articles/11609.html

http://www.ysgj1688.com.ece.gatech.edu/4110/TCPTimers.pdf

http://www.xuancayule.com//RealtimeMantra/Networking/TCP_Slow_Start.pdf

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章