MTU是一個(gè)老概念了,是屬于以太網(wǎng)數(shù)據(jù)鏈路層的概念店乐,而MSS是新的概念,由于MTU和MSS概念都十分重要呻袭,且容易混淆眨八,為了討論清晰,單獨(dú)拎一章節(jié)來討論它們倆左电。
首先我們要說明下討論前提廉侧,本文基于以太網(wǎng)協(xié)議、IP協(xié)議版本使用的是IPv4版本討論篓足。
概括來講段誊,MTU是以太網(wǎng)數(shù)據(jù)鏈路層中約定的數(shù)據(jù)載荷部分最大長度,數(shù)據(jù)不超過它時(shí)就無需分片栈拖。
MSS是傳輸層的概念连舍,由于數(shù)據(jù)往往很大,會超出MTU涩哟,所以我們之前在網(wǎng)絡(luò)層中學(xué)習(xí)過IP分片的知識索赏,將很大的數(shù)據(jù)載荷分割為多個(gè)分片發(fā)送出去诗鸭。
TCP為了IP層不用分片主動(dòng)將數(shù)據(jù)包切割為MSS大小。
一個(gè)等式可見他兩關(guān)系匪淺: MSS = MTU - IP header頭大小 - TCP 頭大小
一参滴、MTU復(fù)習(xí)
MTU全稱是Maximum Transmission Unit强岸,即最大傳輸單元。
在學(xué)習(xí)數(shù)據(jù)鏈路層時(shí)砾赔,我們學(xué)習(xí)過以太網(wǎng)協(xié)議蝌箍,以太網(wǎng)定義了一個(gè)叫做幀的概念,一個(gè)幀中包含如下信息:
此外暴心,我們學(xué)習(xí)了幀的大小妓盲,其中幀頭大小為:
1. 接收方和發(fā)送方的 MAC 地址分別占用 6 個(gè)字節(jié);
2. 第 3 層的協(xié)議用 2 個(gè)字節(jié)編碼专普;
3. CRC 用 4 個(gè)字節(jié)編碼悯衬。
6 x 2 + 2 + 4 = 18。
因此以太網(wǎng)的幀頭一共有 18 個(gè)字節(jié)檀夹,并且以太網(wǎng)中還規(guī)定了最小幀長和最大幀長:
以太網(wǎng)幀的最小尺寸是 64 字節(jié)筋粗,那么一幀中最少報(bào)文長度為46字節(jié)。
以太網(wǎng)幀的最大尺寸是 1518 字節(jié)炸渡,那么一幀中中最大報(bào)文長度為1500字節(jié)娜亿。
其中1500字節(jié)往往就是以太網(wǎng)的MTU值了,傳輸?shù)臄?shù)據(jù)小于它時(shí)蚌堵,就無需切片买决。
太大的數(shù)據(jù)就需要切分,就像一個(gè)超級大包裹需要切分為若干個(gè)小包裹才方便托運(yùn)吼畏。
假設(shè)傳輸100KB的數(shù)據(jù)督赤,則需要切分為多少個(gè)幀進(jìn)行傳輸呢?
100KB=100*1024B泻蚊,由于幀中最大的報(bào)文長度是1500B躲舌,那么100KB/1500B≈68.27,顯然需要69個(gè)以太網(wǎng)幀才能承載藕夫。
二孽糖、MTU與木桶效應(yīng)
一臺機(jī)器上枯冈,不同網(wǎng)卡的MTU也不一樣毅贮,比如我的一臺虛擬機(jī)上的網(wǎng)卡MTU為:
容易想到,一個(gè)包從發(fā)送端傳輸?shù)浇邮斩顺咀啵虚g要跨越很多個(gè)網(wǎng)絡(luò)滩褥,每條鏈路的MTU都可能不一樣,就像開車炫加,有的時(shí)候可以經(jīng)過寬敞的四車道瑰煎,有的時(shí)候不得不行駛于鄉(xiāng)間小路铺然,這個(gè)通信過程中最小的MTU稱為路徑MTU(Path MTU)。
比如第一段鏈路MTU為1200字節(jié)酒甸,第二段鏈路MTU為800字節(jié)魄健,第三段鏈路MTU為1500字節(jié),那么路徑MTU就是最小的800字節(jié)插勤。
路徑 MTU 就跟木桶效應(yīng)是一個(gè)道理沽瘦,木桶的盛水量由最短的那條短板決定,路徑MTU也是由通信鏈條中最小的MTU決定农尖。
基本原理十分簡單析恋,當(dāng)一方發(fā)送了超過MTU的數(shù)據(jù)包后,對方會返回一個(gè)ICMP錯(cuò)誤包盛卡,告知發(fā)送方包太大需要分片助隧,并且告知發(fā)送方下一個(gè)分片的大小按照比如MTU=1200來計(jì)算,由于MTU取小者滑沧,那么A就需要隨之調(diào)整MTU為1200字節(jié):
三并村、用ping命令小試牛刀
下面我們實(shí)際抓包驗(yàn)證下,不過在驗(yàn)證前滓技,我們需要重新認(rèn)識下ping命令橘霎。
我們之前學(xué)習(xí)過了ping命令,其原理是基于ICMP協(xié)議殖属,而ICMP協(xié)議實(shí)際上是封裝在IP數(shù)據(jù)中的姐叁,首部為8字節(jié)長度,關(guān)于ICMP我們已經(jīng)討論過洗显,這里不再贅述外潜。
ping后面是可以跟著一些參數(shù)滿足我們的一些測試用例的,我們將使用到的命令是:
ping? 192.168.56.102? -l 1472? -f? -n 1
如何查看后續(xù)參數(shù)的含義呢挠唆,我們在windows上的窗口界面輸入:
ping -help
-l 1472表示發(fā)送的數(shù)據(jù)包大小处窥,單位是字節(jié);
-n表示只發(fā)送一個(gè)請求玄组,因?yàn)閣indows下默認(rèn)會自動(dòng)發(fā)送四個(gè)數(shù)據(jù)包請求滔驾;
-f表示不分片,實(shí)際上就是IPv4固定首部中的標(biāo)志位中的DF字段:
標(biāo)志位中間位即第2位記為DF(Don't Fragment)俄讹,意思是原數(shù)據(jù)報(bào)能否分片哆致。
當(dāng)值為1時(shí),表示該數(shù)據(jù)報(bào)不允許分片患膛,當(dāng)值為0時(shí)摊阀,表示該數(shù)據(jù)報(bào)允許分片。
我們下面分別執(zhí)行兩條命令,來看下神奇情況的發(fā)生:
可以看到胞此,我們前后發(fā)出了兩個(gè)ping請求臣咖,第一次攜帶1472字節(jié)數(shù)據(jù),第二次攜帶1473字節(jié)數(shù)據(jù)漱牵,并且都設(shè)置了DF為1即不允許分片夺蛇。
僅僅相差一個(gè)字節(jié),為什么在結(jié)果上出現(xiàn)了天壤之別呢酣胀?
首先ICMP首部固定為8字節(jié)蚊惯,IP首部固定部分是20字節(jié),我們這里沒有額外部分灵临,加上1472字節(jié)的數(shù)據(jù)截型,正好就是以太網(wǎng)幀中最大1500字節(jié)大小,即8+20+1472=1500字節(jié)儒溉。
對本次ping的抓包結(jié)果如下:
不然理解宦焦,第一次請求正好是1500字節(jié),沒有超過MTU限制顿涣,所以可以傳輸成功波闹,而第二次超出了一個(gè)字節(jié),又不允許分片涛碑,因此傳輸失敗精堕。
對于第二種情況,如果ping命令后面不攜帶-f參數(shù)蒲障,也是可以ping成功的歹篓,只是在路上會被切分為兩個(gè)包。
我們繼續(xù)來抓包證明自己的想法揉阎,去掉-f選項(xiàng)庄撮,允許分片,執(zhí)行命令:
ping 192.168.56.102 -l 1473 -n 1
我們看到了fragmented ip protocol字眼毙籽,中文意思是分段ip協(xié)議洞斯,說明1473字節(jié)的數(shù)據(jù)被分片了,我們且來看第一個(gè)分片報(bào)文詳情:
繼續(xù)看下一個(gè)報(bào)文詳情:
也可以注意到一個(gè)細(xì)節(jié)坑赡,第二個(gè)報(bào)文段中不包含ICMP首部烙如。此外可以注意到wireshark上顯示的包length為35長度,之前不是說過至少是60字節(jié)的嗎毅否?(加上FCS校驗(yàn)應(yīng)該是64字節(jié))
實(shí)際上亚铁,如果數(shù)據(jù)部分小于以太網(wǎng)幀需要的最小的46字節(jié)時(shí),就會在以太網(wǎng)層自動(dòng)填充0搀突,使得數(shù)據(jù)達(dá)到46字節(jié)刀闷,從而達(dá)到最小64字節(jié)的幀長度要求熊泵。而這里顯示35字節(jié)大概率是因?yàn)閣ireshark捕獲的時(shí)候還未進(jìn)行填充仰迁,從而顯示出了這個(gè)異常的長度包(對于這一點(diǎn)如果有錯(cuò)誤還請指正)甸昏。
四、壓軸登場:MSS
MSS的英文全稱叫Max Segment Size徐许,是TCP最大段大小施蜜。
在建立TCP連接的同時(shí),也可以確定發(fā)送數(shù)據(jù)包的單位雌隅,我們稱為MSS翻默,這個(gè)MSS正好是IP中不會被分片處理的最大數(shù)據(jù)長度。
TCP在傳送大量數(shù)據(jù)時(shí)恰起,是以MSS的大小將數(shù)據(jù)進(jìn)行分割發(fā)送的修械,重發(fā)時(shí)也是以MSS為單位。
MSS是在三次握手的時(shí)候检盼,在兩端主機(jī)之間被計(jì)算得出肯污,兩端主機(jī)在發(fā)出建立連接的請求時(shí),會在TCP首部中寫入MSS選項(xiàng)吨枉,告訴對方自己的接口能夠適應(yīng)的MSS的大小蹦渣,然后在兩者之間選擇一個(gè)較小的值投入使用。
從以上描述中可以看出來:
MSS = MTU - IP header頭大小 - TCP 頭大小
這樣一個(gè) MSS 的數(shù)據(jù)恰好能裝進(jìn)一個(gè) MTU 而不用分片貌亭。
在我們熟悉的以太網(wǎng)中柬唯,TCP的MSS最大值是:以太網(wǎng)MSS=1500(MTU)-20(IP首部長度)-20(TCP首部大小)=1460字節(jié)
好了,理論介紹完畢圃庭,下面我們來看下實(shí)際抓包锄奢。
我的虛擬機(jī)上安裝了一個(gè)nginx,端口使用的是熟知端口號80剧腻,我在本地客戶端通過curl命令訪問nginx的服務(wù):
從下圖抓包中可以看到斟薇,MSS的值是在三次握手的SYN報(bào)文中商量出來的,可以看到互相說明自己允許的最大段大小都是1460字節(jié)恕酸,那么MSS的值就可以取為1460堪滨。
在以太網(wǎng)協(xié)議中,一般情況下MTU是1500字節(jié)蕊温,MSS為1460字節(jié)(相差20字節(jié)的IP首部+20字節(jié)的TCP首部)袱箱,不過以上是基于IPv4協(xié)議討論的,在IPv6中义矛,IP首部長度是40字節(jié)发笔,那么MSS一般就是1440字節(jié)了。
MSS選項(xiàng)只能出現(xiàn)在SYN報(bào)文中凉翻,為此SYN報(bào)文TCP頭部里包含了12字節(jié)的選項(xiàng)(Options)字段了讨,可以清晰看到里面有一個(gè)MSS選項(xiàng),所以本次的TCP的握手報(bào)文中的TCP首部長度為32字節(jié),即20字節(jié)的固定首部加12字節(jié)的可變首部前计,整體為4字節(jié)的整數(shù)倍胞谭。
五、參考
傳輸層篇-MTU和MSS
https://mp.weixin.qq.com/s/ZMV2izeYkBIqjPhsv_-wdw