TCP IP協議中,傳輸層將訊息分割成多個資料報時,如何獲知網路層最大傳輸單元MTU的長度?

時間 2021-05-30 00:06:17

1樓:車小胖

傳輸層協議TCP、UDP獲得本地介面的MTU還是很簡單的,只要通過簡單的函式呼叫即可。可是,得到本地的MTU值並不能保證本地發出的IP報文,在通往目的地的路徑上不被分片。

根據木桶理論,乙個木桶能裝多少水,不是由最高的木板來決定的,而是由最低的木板來決定的。同理,在通向目的地的路徑上,決定傳輸最大單元尺寸是最小的路由器的MTU,而不是最大的MTU。

儘管獲知通訊雙方之間路徑最小MTU有一定難度,但是TCP協議還是決定用自己的方法來找到它。

TCP使用MSS option 在握手連線時,雙方互相交換各自的MSS,然後雙方約定使用兩個MSS中的小者,但這種方法並不有效。

比如客戶端MTU = 1500, 伺服器端MTU = 1500,雙方的MSS = 1460,雙方就協商使用1460 byte 來傳輸TCP segment。

問題來了,客戶端通向ISP的光纖路由器是PPPoE撥號,將會在正常的IP報文頭新增8 byte的PPPoE頭,相當於變相擠占了IP報文8 byte的空間,留給IP報文的MTU = 1500 -8 =1492,那麼客戶端與伺服器的1500 byte 的IP報文最終會被分片。

如何探測路徑中的最小的MTU?

只要讓IP報文設定DF= 1即可,這樣一旦需要分片而無法分片,會傳送錯誤訊息通知源。源主機就會獲悉最小的MTU的數值,源主機的IP層會記錄一條特殊的主機路由,這條主機路由通向唯一的目的地,並標註其最小MTU,這樣以後和該目的地主機的通訊將使用該最小MTU。

同時,源主機IP層會通過訊息通知的方式,通知TCP關於路徑中最小MTU,這樣該TCP session會相應地減小自己的最大傳輸單元。

這種方法固然好,但是由於某些路由器可能禁止了ICMP錯誤通知功能,動態路徑MTU檢測,往往造成通訊障礙。

Windows 10 統一使用 MTU = 1300的方法,可能是乙個較好的方法,可以避免99%+以上網路場景的分片。

2樓:宇文拓

我想,你應該是想獲得一條網路路徑上所有節點中最小的mtu吧?如果是這樣,乙個可行的方法是包裝指定長度的ping包傳送給對端,同時設定不可拆包的標誌,如果能收到返回,說明網路路徑上最小的mtu不比這個小,然後再增大包大小,直到收不到回包為止,之前成功的最大包大小就是這個mtu值了。可以檢視ping命令的幫助,看哪個選項控制這些引數。

計算的時候注意也要把IP包頭的大小算在內。

關於java socket程式設計中傳輸協議層和應用層協議的乙個疑問,求指教?

Mr.Zhang 瀉藥。我來回答第乙個問題好了。結論先行 必須!傳輸層 用來對資料進行流量控制以及對資料報的大小進行嚴格控制。應用層 用來對軟體提供網路服務的介面,如此才能是程式呼叫網路服務。so? 鮑一豐 必須。沒有預設。可以,一般不用。下面是科普,你就是一台電腦,你收到一快遞了,快遞就是你收到的...

為什麼tcp ip協議沒有會話層和表示層?

李勇 看下tcp ip的發展史就知道了。70 80年代設計的tcp ip協議,已經非常成熟了,之後除了ipv6 到現在還是ipv4為主 基本都是 縫縫補補又三年 的狀態。個人覺得原因之一 tcp ip over all,這個all就是連當初tcp的設計者們都不知道未來應用層協議是啥樣子,總得 可擴充...

傳輸層協議和應用層協議有什麼區別,為什麼http即可以做傳輸層協議也可以做應用層協議呢?

隨心 傳輸層協議有tcp和udp,http協議叫做超文字傳輸協議,是建立在傳輸層協議之上的屬於應用層的協議。沒有傳輸層協議,http協議就不行! HTTP是應用層協議,TCP和UDP是傳輸層協議。通俗地說,應用層協議其實就是在傳輸層協議上標識了埠號。例如 HTTP協議預設使用了TCP協議的80埠。F...