報(bào)文為什么要分片
一個(gè)鏈路層數(shù)據(jù)報(bào)能承載的最大數(shù)據(jù)量稱為最大傳送單元(MTU)。
因?yàn)镮P數(shù)據(jù)報(bào)(IP頭+DATA)被封裝在鏈路層數(shù)據(jù)報(bào)中,故鏈路層的MTU嚴(yán)格地限制著IP數(shù)據(jù)報(bào)的長度,
而且在IP數(shù)據(jù)報(bào)的源與目的地路徑上的各段鏈路可能使用不同的鏈路層協(xié)議,有不同的MTU.
例如,以太網(wǎng)的MTU為1500字節(jié),而許多廣域網(wǎng)的MTU不超過576字節(jié)。
當(dāng)IP數(shù)據(jù)報(bào)的總長度大于鏈路MTU時(shí),
就需要將IP數(shù)據(jù)報(bào)中的數(shù)據(jù)分裝在兩個(gè)或更多個(gè)較小的IP數(shù)據(jù)報(bào)中,
這些較小的數(shù)據(jù)報(bào)叫做片。
互聯(lián)網(wǎng)協(xié)議使網(wǎng)絡(luò)互相通信。設(shè)計(jì)要迎合不同物理性質(zhì)的網(wǎng)絡(luò);
它是獨(dú)立于鏈路層使用的基礎(chǔ)傳輸技術(shù)。具有不同硬件的網(wǎng)絡(luò)通常會發(fā)生變化,不僅在傳輸速度,而且在最大傳輸單元(MTU)。當(dāng)一個(gè)網(wǎng)絡(luò)要的數(shù)據(jù)報(bào)發(fā)送到具有較小MTU的一個(gè)網(wǎng)絡(luò),它可能片段的數(shù)據(jù)報(bào)。在IPv4中,這個(gè)功能被放置在因特網(wǎng)層,并且在IPv4路由器,這因此只需要這個(gè)層作為最高的一個(gè)在其設(shè)計(jì)中實(shí)現(xiàn)的處理。
與此相反,IPv6的,下一代互聯(lián)網(wǎng)協(xié)議的,不允許的路由器來執(zhí)行分片; 發(fā)送數(shù)據(jù)包之前,主機(jī)必須確定路徑MTU。
ipv4 分片報(bào)文
IPv4分片的特點(diǎn)
標(biāo)志
一個(gè)三比特字段遵循與用于控制或識別片段。他們是(按順序,從高分以低位):
0:保留; 必須為零。
1位:不分段(DF)
2位:更多片段(MF)
如果DF標(biāo)志被設(shè)置,并且分片需要來路由分組,則該分組被丟棄。這可以發(fā)送分組到不具有足夠的資源來處理破碎的宿主時(shí),可以使用。它也可用于路徑MTU發(fā)現(xiàn)由主機(jī)IP軟件,可以自動或使用診斷工具例如手動平或跟蹤路由。對于未分段的數(shù)據(jù)包,對MF標(biāo)志被清除。對于分片包,除了最后的所有片段具有MF標(biāo)志設(shè)置。最后片段具有一個(gè)非零片偏移量字段,從一個(gè)未分段的分組區(qū)分它。
分片偏移
片段偏移字段以8字節(jié)塊為單位進(jìn)行測量。它是13位長,并指定特定相對于原始未分段的IP數(shù)據(jù)報(bào)的開始的片段的偏移量。零第一片段已偏移。這允許最多(2偏移13(次方)- 1)×8 =字節(jié)65,528,這將超過65,535字節(jié)的最大IP報(bào)文長度與包括報(bào)頭長度(+ 65,528 20 = 65548字節(jié))。
一般來說我們都知道MTU是1500字節(jié),因此超過1500字節(jié)的數(shù)據(jù)就需要進(jìn)行ip分片。
1、分片由IPv4頭部中的標(biāo)識(Identification)、分片偏移(Fragment offiet)和更多分片(More Fragments, MF)字段控制,分片的標(biāo)識(Identification)都是同樣的而且分片偏移(Fragment offiet)是以8字節(jié)為單位的偏移。
2、分片:源和目的端口號的UDP(協(xié)議)頭部只出現(xiàn)在第一個(gè)分片里
3、重組:IP分片在目的地的網(wǎng)絡(luò)層被重新組裝。
目的主機(jī)使用IP首部中的標(biāo)識、標(biāo)志和片偏移字段來完成對片的重組。
同樣的標(biāo)識和不同的偏移讓接收方可以對分片進(jìn)行重組,
當(dāng)MF = 0的分片被接收到時(shí),重組程序才能確定原始數(shù)據(jù)報(bào)的長度,
它等于分片偏移字段的值(乘以8)加上當(dāng)前分片IPv4總長度字段的值。。
標(biāo)識(Identification):
當(dāng)創(chuàng)建一個(gè) IP數(shù)據(jù)報(bào)時(shí),源主機(jī)為該數(shù)據(jù)報(bào)加上一個(gè)標(biāo)識號。
當(dāng)一個(gè)路由器需要將一個(gè)數(shù)據(jù)報(bào)分片時(shí),形成的每個(gè)數(shù)據(jù)報(bào)(即片)都具有相同的原始數(shù)據(jù)報(bào)的標(biāo)識號。
當(dāng)目的主機(jī)收到來自同一發(fā)送主機(jī)的一批數(shù)據(jù)報(bào)時(shí),它可以通過檢查數(shù)據(jù)報(bào)的標(biāo)識號以確定哪些數(shù)據(jù)報(bào)是屬于同一個(gè)原始數(shù)據(jù)報(bào)的片。
更多分片(More Fragments, MF)
IP首部中的標(biāo)志位有3個(gè)比特,但只有后2個(gè)比特有意義,分別是MF位和DF位(Don’t Fragment),標(biāo)志指明該數(shù)據(jù)報(bào)后面是否還有更多的分組。
只有當(dāng)DF=0時(shí),該IP數(shù)據(jù)報(bào)才可以被分片。
MF則用來告知目的主機(jī)該IP數(shù)據(jù)報(bào)是否為原始數(shù)據(jù)報(bào)的最后一個(gè)片。
當(dāng)MF=1時(shí),表示相應(yīng)的原始數(shù)據(jù)報(bào)還有后續(xù)的片;
當(dāng)MF=0時(shí),表示該數(shù)據(jù)報(bào)是相應(yīng)原始數(shù)據(jù)報(bào)的最后-一個(gè)片。
目的主機(jī)在對片進(jìn)行重組時(shí),使用片偏移字段來確定片應(yīng)放在原始IP數(shù)據(jù)報(bào)的哪個(gè)位置。
分片偏移(Fragment offiet)
偏移量是用來記錄每個(gè)分片所在的位置,
偏移量=相對分片報(bào)文長度/8;
假設(shè)一共傳輸3800字節(jié),mtu為1400字節(jié),由于固定ip首部為20字節(jié),
因此實(shí)際傳輸長度為1420字節(jié),所以只需要傳輸三次,1400+1400+1000,
那么第一片偏移為0,第二片偏移=1400/8=175,第三次偏移=2800/8=350.
分片偏移量計(jì)算。
例:
考慮向一條具有1500字節(jié)的MTU的鏈路發(fā)送一個(gè)8000字節(jié)的數(shù)據(jù)報(bào)(首部20字節(jié),數(shù)據(jù)部分7980字節(jié)),
假定初始化數(shù)據(jù)報(bào)具有序列號321,這將會生成多少個(gè)片?它們的特征是什么?
答:
因?yàn)镮P數(shù)據(jù)報(bào)首部占20字節(jié),因此在每個(gè)分片中片的大小是1500-20=1480個(gè)字節(jié),
故原始數(shù)據(jù)報(bào)中7980字節(jié)數(shù)據(jù)必須被分配到7980/1480=6個(gè)片中。
所以7980字節(jié)數(shù)據(jù)必須被分配到6個(gè)獨(dú)立的片中(每個(gè)片也是一一個(gè)IP數(shù)據(jù)報(bào))。
由于偏移值的單位是8字節(jié),所以除了最后一個(gè)片外,其他所有片中的有效數(shù)據(jù)載荷都是8的倍數(shù)。
每個(gè)片的標(biāo)識號都為321.前5個(gè)片的MF=1(還有分片),最后一個(gè)片的MF=0(表示最后一個(gè)分片)
例:分片報(bào)文實(shí)例分析
1、首片
2,中間片
灰底的Fragment offset:1480 那行對應(yīng)的十六進(jìn)制碼是藍(lán)底的0X20b9,
剛開始很疑惑為何十進(jìn)制的1480對應(yīng)的是0x20b9,怎么算都不對啊,不知道讀者您是不是遇到了這樣的疑惑!
參考RFC791中相關(guān)字段的說明 才明白原來這個(gè)1480指的是偏移的實(shí)際字節(jié)而不是 fragment offset字段中比特位對應(yīng)的十進(jìn)制數(shù)值。
該字段的是以8個(gè)“八比特組”為單位的,所以1480在該字段的值是除以8之后的185,換算成二進(jìn)制就是0 0000 1011 1001,因?yàn)榍懊孢€有個(gè)值為001的3比特的Flag字段,所以加上Flag字段后其二進(jìn)制值是0010 0000 10111001,換算成二進(jìn)制就是20b9。請自己算算吧。弄不明白的需要先掌握數(shù)據(jù)包結(jié)構(gòu)及進(jìn)制等基礎(chǔ)了。
查閱RFC791,所述如下:
The data of the long datagram is divided into two portions on a 8 octet (64 bit) boundary(the second portion might not be an integral multiple of 8 octets,but the first must be).
分片偏移是要按8 octet來對齊的,也就是按8字節(jié)對齊(分片偏移:即8字節(jié)為單位),所以這里的一個(gè)單位應(yīng)該是8字節(jié), 185單位 * 8字節(jié) =1480字節(jié),也就對的上了。
關(guān)于octet,大多數(shù)因特網(wǎng)標(biāo)準(zhǔn)使用八位組(octet)這個(gè)術(shù)語而不是使用byte來表示8位的量,早期的一些系統(tǒng)的byte表示的bit不一致,有的byte表示10bits,所以octet是準(zhǔn)確定義的,1 octet = 8 bit;
另外,這里是標(biāo)識 + 分片偏移,一起組合成的十六進(jìn)制碼 20b9,wireshark 中也清楚展示了,flags
是最高三位的 001,分片偏移是剩下的13位: 0 0000 1011 1001, 所以, 20b9 = 0010 0000 1011 1001.
3、最后一片
從Wireshark抓包來看IP分片
例:下圖是一個(gè)長度為3000字節(jié)的udp包(包括了udp包頭的8個(gè)字節(jié))。
原始數(shù)據(jù)報(bào)要加上ipv4包頭為3020字節(jié),它超過了MTU的限制,因此發(fā)送的時(shí)候會進(jìn)行分片。
第一個(gè)分片中實(shí)際傳送了1472字節(jié)的udp數(shù)據(jù)和8字節(jié)udp包頭。
此時(shí)偏移為0,因?yàn)榻酉聛磉€有數(shù)據(jù)包要發(fā)因此MF置為1
第二個(gè)分片傳送1480字節(jié)的udp數(shù)據(jù),因?yàn)榈谝粋€(gè)分片已經(jīng)傳送了1480,因此這里的偏移為1480/8 = 185,因?yàn)榻酉聛磉€有數(shù)據(jù)包要發(fā)因此MF置為1
最后一個(gè)分片傳送剩下的40字節(jié)數(shù)據(jù),并將MF置為0,此時(shí)接收方可以通過370*8+60來算出原始數(shù)據(jù)報(bào)的長度,因此也知道了udp包的大小為3000字節(jié)(減掉ip包頭的20字節(jié))。
wireshark中的抓到的報(bào)文(wireshark默認(rèn)設(shè)置)
我們發(fā)現(xiàn)它和我們上一節(jié)講的不太一樣,UDP包按理應(yīng)該是第一個(gè)出現(xiàn),之后跟著一串分片后的IPv4包。而打開上面截圖里所有的IPv4包我們發(fā)現(xiàn)它們的MF標(biāo)志全都是1,且最后的udp包的length明顯大于了MTU。
這是因?yàn)閣ireshark的首選項(xiàng)中自動開啟了重組分片數(shù)據(jù)的選項(xiàng)。這個(gè)默認(rèn)開啟的選項(xiàng)能直接幫我們重組原udp數(shù)據(jù)包并用它替換了MF=0的那個(gè)IPv4數(shù)據(jù)包,因此在開啟該選項(xiàng)時(shí)我們是找不到MF=0的數(shù)據(jù)包的。
我們打開第一個(gè)UDP包,它的數(shù)據(jù)如下:
我們可以知道雖然它包頭中的長度給出的Length為8537(包含8個(gè)字節(jié)包頭,實(shí)際數(shù)據(jù)為8529字節(jié)),但是真實(shí)的Data里只有1472字節(jié),1472+8(UDP包頭)+20(IP包頭) = MTU。我們再看這一組最后一個(gè)IPv4包:
我們可以看到它的MF=0,因此計(jì)算925*8+1157 = 8557,這是原始的數(shù)據(jù)報(bào)文,減掉20字節(jié)的IP包頭,恰好為8537字節(jié)。與UDP包中所給的Length值一樣。
ipv6分片
ipv6分片特點(diǎn)
IPv6并沒有完全放棄分片機(jī)制,只是說它用一種完全不同的機(jī)制來實(shí)現(xiàn)分片。
熟悉IPv4的肯定知道IP分片這個(gè)特性,它在某種意義上讓應(yīng)用程序忘記了數(shù)據(jù)包還有
大小這個(gè)屬性,也就是說,應(yīng)用程序可以發(fā)送小于IP頭規(guī)定的最長65535字節(jié)的任意大
小的數(shù)據(jù)包。
IPv4嚴(yán)格采納分層模型,讓路徑MTU這種事做到對應(yīng)用程序完全透明而無感知。
如果路徑MTU太小不足以讓大數(shù)據(jù)報(bào)文通過,那么分片這種機(jī)制便開始起作用。
而IPv6網(wǎng)絡(luò)的分片和實(shí)現(xiàn),網(wǎng)絡(luò)只管轉(zhuǎn)發(fā),分片這種端到端功能自然需要卸載到通信雙方終
端主機(jī)!IPv6禁止中間節(jié)點(diǎn)設(shè)備對IP報(bào)文進(jìn)行分片。分片只能在端到端進(jìn)行!
IPv6禁止了中間設(shè)備分片,卸載了一些信息處理流程。最終目的是讓IPv6報(bào)頭成為固定
的長度,且內(nèi)部字段對齊,便于高效預(yù)取或者直接通過固定硬件處理,從而達(dá)到提高
處理性能的目的。
既然在路由器等轉(zhuǎn)發(fā)設(shè)備上去掉分片機(jī)制這么好,那么為什么在端主機(jī)還允許分片,
直接全部禁止了不更好嗎?
我們知道,應(yīng)用層對于數(shù)據(jù)報(bào)文的解釋,它代表了一個(gè)數(shù)據(jù)報(bào)呢,還是說代表一個(gè)流。
如果是代表一個(gè)流,那么一切OK,只要持續(xù)發(fā)送數(shù)據(jù)流字節(jié)即可,
網(wǎng)絡(luò)情況好了就一次多發(fā)幾個(gè)字節(jié),網(wǎng)絡(luò)情況不好了就少發(fā)幾個(gè)甚至發(fā)1個(gè)字節(jié),都無所謂。
但是對于用戶數(shù)據(jù)報(bào),比如UDP報(bào)文這種,就不行了。
UDP報(bào)文是嚴(yán)格按照報(bào)文長度發(fā)送和接收的,應(yīng)用程序之間定義了一個(gè)2000字節(jié)的應(yīng)用層協(xié)
議,那么一個(gè)報(bào)文就必須是2000字節(jié)長,不能說你IPv6為了轉(zhuǎn)發(fā)效率而不讓人家發(fā)長報(bào)文吧。
因此,IPv6不能完全放棄分片機(jī)制,只是說它用一種完全不同的機(jī)制來實(shí)現(xiàn)分片:
1.分片和重組只能在端主機(jī)進(jìn)行。
2.分片信息不在IPv6協(xié)議標(biāo)準(zhǔn)頭里,而單獨(dú)設(shè)計(jì)一個(gè)擴(kuò)展頭存放。
如此做,IPv6相當(dāng)于:
報(bào)文始發(fā)站完全可以通過PMTU知曉鏈路最小MTU,這完全是端到端行為,卸載了跟網(wǎng)絡(luò)沒有毛線關(guān)系的額外動作。
IPv6等效于IPv4永久無條件設(shè)置Don’t Fragment標(biāo)識(但并不絕對,對于1280以下MTU則例外!后面講)。
卸載了IPv4頭的分片相關(guān)字段后,這些分片字段便放在了擴(kuò)展頭里面
如果僅僅是以上的簡單規(guī)定,那么在實(shí)現(xiàn)的時(shí)候?qū)龅胶芏酂o法避開的問題:
在端主機(jī)只知道自己的鏈路MTU,如何知道中間路徑的最小MTU,即如何確定要不要分片?
計(jì)算通過MTU發(fā)現(xiàn)找到了最小MTU,如何保證實(shí)際數(shù)據(jù)傳輸時(shí)就是按照MTU探測時(shí)的路徑走的?
…
PMTU的實(shí)現(xiàn)過程,我這里依然不談,我要說的是,IPv6為了讓分片不那么頻繁進(jìn)行,依靠宣傳力量 強(qiáng)制建議了一個(gè)規(guī)則 ,即 所有傳輸IPv6報(bào)文的鏈路都要提供1280字節(jié)以上的MTU容量! 呵呵,強(qiáng)制建議,意思是你必須實(shí)現(xiàn)它,如果你不實(shí)現(xiàn),我也沒有辦法,畢竟為了保持網(wǎng)路的透明性,不能把事情做絕,但是求求你實(shí)現(xiàn)它好嗎?我這可是IPv6的標(biāo)準(zhǔn)??!
那么,為什么是1280字節(jié)?這是一個(gè)權(quán)衡的結(jié)果。
如果限制的最小MTU太小,那么將會有很多鏈路為了成本或者其它博弈結(jié)論考慮,提供小的MTU,如此一來,這種 不得不進(jìn)行 的補(bǔ)救分片方案就會非常多,相當(dāng)于抵消了IPv6禁止分片的收益。
小分片非常容易助力網(wǎng)路的擁塞,如果擁塞控制隊(duì)列機(jī)制是基于包而不是基于自己的話,這會更加嚴(yán)重,并且小分片,特別是TCP段的小分片,一個(gè)丟失則整個(gè)重傳,這會增加鏈路的重傳率。
考慮到隧道封裝協(xié)議的廣泛存在以及以太網(wǎng)1500字節(jié)MTU的普遍性,1280空出220字節(jié)給隧道使用,足夠了。
不管大了還是小了都不好,那么什么樣的限制最好呢?
關(guān)于這點(diǎn),我倒是有個(gè)形而上的想法,即整個(gè)互聯(lián)網(wǎng)上所有鏈路MTU的方差,均差越小越好!即 大家的MTU都往使用最多的MTU的附近湊! 由于我們需要限制的是最小MTU,那么就是使用最多的1500,其下面不遠(yuǎn)的位置,照顧到隧道協(xié)議,空出足夠的220字節(jié),就選1280字節(jié)!完美。
那如果就有人有意或者無意,考慮到底層鏈路的硬件投資,考慮到兼容性,其MTU小于1280字節(jié),怎么辦?
沒辦法,還是要分片的,這就是 不得不進(jìn)行的分片
1、第一片
2、中間片
文章來源:http://www.zghlxwxcb.cn/news/detail-805691.html
3、最后一片
文章來源地址http://www.zghlxwxcb.cn/news/detail-805691.html
到了這里,關(guān)于TCP/IP協(xié)議專欄——分片報(bào)文詳解——網(wǎng)絡(luò)入門和工程維護(hù)必看的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!