藉助wireshark深入分析---tcp傳輸窗口

tcp傳輸窗口解析——藉助wireshark深入分析

tcp傳輸報文時,會有“往返”的需要。因爲發包之後並不知道對方能否收到,要一直等到確認包到達,這樣就花費了一個往返時間。假如每發一個包就停下來等確認,
一個往返時間裏就只能傳一個包,這樣的傳輸效率太低了。最快的方式應該是一口氣把所有包發出去,然後一起確認。但現實中也存在一些限制:接收方的緩存(接收窗口)可能一下子接受不了這麼多數據;網絡的帶寬也不一定足夠大,一口氣發太多會導致丟包事故。所以,發送方要知道接收方的接收窗口和網絡這兩個限制因素中哪一個更嚴格,然後在其限制範圍內儘可能多發包。這個一口氣能發送的數據量就是傳說中的 TCP發送窗口。發送窗口對性能的影響有多大?一圖勝千言,下圖顯示了發送窗口爲 1個 MSS(即每個 TCP包所能攜帶的最大數據量)和 2個 MSS時的差別。在相同的往返時間裏,右邊比左邊多發了兩倍的數據量。而在真實環境中,發送窗口常常可以達到數十個 MSS。


1.每個包的 TCP層都含有“ window size:”(也就是 win =)的信息。這個值表示發送窗口的大小嗎?

這不是發送窗口,而是在向對方聲明自己的接收窗口。

從下截圖中可以看到, 61.135.169.121 向 192.168.1.121 聲明自己的接收窗口是 772字節。 192.168.1.121 收到之後,就會把自己的發送窗口限制在 772字節之內。很多教科書上提到的滑動窗口機制,說的就是這兩個窗口的關係,本文就不再贅述了。假如接收方處理數據的速度跟不上接收數據的速度,緩存就會被佔滿,從而導致接收窗口爲 0。接收方持續向 發送方 聲明自己的接收窗口是 win = 0,所以 發送方的發送窗口就被限制爲 0,意味着那段時間發不出數據。


其中在截圖中看到的win size 和 Calculated Windows Size ,可以看到這兩個值是不一樣的。
再關注一下下面的那個字段值:“Window size scalling factor”,
會有一個這樣的算術關係:
win size * win size scalling factor = calculated win size
這裏也就是 772 * 32 = 24704

window size value表示報文的值,calculated window size表示放大後的值,也就是實際可用的值,而 scalling factor 就相當於放大的倍數,具體這個字段代表的含義,可以往下看(第5點有寫)。

2.在包裏看出發送窗口的大小呢?

很遺憾,沒有簡單的方法,有時候甚至完全沒有辦法。因爲,當發送窗口是由接收窗口決定的時候,我們還可以通過“ window size:”的值來判斷。而當它由網絡因素決定的時候,事情就會變得非常複雜,今天這裏暫時不涉及,後面會單獨拿出來討論。大多數時候,我們甚至不確定哪個因素在起作用,只能大概推理。比如,如果接收方聲明它的接收窗口等於 0,那接收窗口肯定起了限制作用(因爲不可能再小了),因此可以大膽地判斷髮送窗口就是 0。還可以觀察如果發送方發送了2個包就需要等待確認,那可能發送窗口就是這兩個包的長度。

3.發送窗口和 MSS有什麼關係?

發送窗口決定了一口氣能發多少字節,而 MSS決定了這些字節要分多少個包發完。舉個例子,在發送窗口爲 16000字節的情況下,如果 MSS是 1000字節,那就需要發送 16000/ 1000 = 16個包;而如果 MSS等於 8000,那要發送的包數就是 16000/ 8000 = 2了。

4.發送方在一個窗口裏發出 n個包,是不是就能收到 n個確認包?

不一定,確認包一般會少一些。由於 TCP可以累積起來確認,所以當收到多個包的時候,只需要確認最後一個就可以了。可能會存在客戶端用一個包確認了它收到的 10個包。這個就需要根據ack報文的num 進行確定了。

比如如下截圖可以看到ack num = seq num + len
分別用絕對 seq num 和相對 seq num 看一下:


這樣就可以確定這個ack報文是確認的哪個seq報文,一個ack報文確認多個請求報文的場景,實在是沒有合適的場景報文。

5.經常聽說“ TCP Window Scale”這個概念,它究竟和接收窗口有何關係?

在 TCP剛被髮明的時候,全世界的網絡帶寬都很小,所以最大接收窗口被定義成 65535字節。隨着硬件的革命性進步, 65535字節已經成爲性能瓶頸了,怎麼樣才能擴展呢? TCP頭中只給接收窗口值留了 16 bit,肯定是無法突破 65535 (216 − 1)的。 1992年的 RFC 1323中提出了一個解決方案,就是在三次握手時,把自己的 Window Scale信息告知對方。由於 Window Scale放在 TCP頭之外的 Options中,所以不需要修改 TCP頭的設計。 Window Scale的作用是向對方聲明一個 Shift count,我們把它作爲 2的指數,再乘以 TCP頭中定義的接收窗口,就得到真正的 TCP接收窗口了。如下圖,這是一個很久版本的wireshark截圖了,從底部可以看到 10. 32. 106. 159告訴 10. 32. 106. 103說它的 Shift count是 5。 25等於 32,這就意味着以後 10. 32. 106. 159聲明的接收窗口要乘以 32纔是真正的接收窗口值。


如果使用新版的wireshark,就是前面的那張圖,顯示上已經有所不同了,不過字段含義還是一樣的。

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