九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
動(dòng)圖圖解!既然IP層會(huì)分片,為什么TCP層也還要分段?|路由器|ip|tcp|數(shù)據(jù)包|報(bào)文



文章持續(xù)更新,可以微信搜一搜「golang小白成長(zhǎng)記」第一時(shí)間閱讀,回復(fù)【教程】獲golang免費(fèi)視頻教程。本文已經(jīng)收錄在GitHub https://github.com/xiaobaiTech/golangFamily (點(diǎn)擊閱讀原文直達(dá)), 有大廠面試完整考點(diǎn)和成長(zhǎng)路線,歡迎Star。
什么是TCP分段和IP分片

我們知道網(wǎng)絡(luò)就像一根管子,而管子吧,就會(huì)有粗細(xì)。

一個(gè)數(shù)據(jù)包想從管子的一端到另一端,得過這個(gè)管子。(廢話)

但數(shù)據(jù)包的量有大有小,想過管子,數(shù)據(jù)包不能大于這根管子的粗細(xì)。

問題來了,數(shù)據(jù)包過大時(shí)怎么辦?

答案比較簡(jiǎn)單。會(huì)把數(shù)據(jù)包切分小塊。這樣數(shù)據(jù)就可以由大變小,順利傳輸。


數(shù)據(jù)分片

回去看下網(wǎng)絡(luò)分層協(xié)議,數(shù)據(jù)先過傳輸層,再到網(wǎng)絡(luò)層。

這個(gè)行為在傳輸層和網(wǎng)絡(luò)層都有可能發(fā)生。

在傳輸層(TCP協(xié)議)里,叫分段。

在網(wǎng)絡(luò)層(IP層),叫分片。(注意以下提到的IP沒有特殊說明的情況下,都是指IPV4

那么不管是分片還是分段,肯定需要按照一定的長(zhǎng)度切分。

TCP里,這個(gè)長(zhǎng)度是MSS。

IP層里,這個(gè)長(zhǎng)度是MTU。

MSS和MTU是什么關(guān)系呢?這個(gè)在里簡(jiǎn)單提到過。這里單獨(dú)拿出來。

MSS是什么

MSS:Maximum Segment Size。TCP 提交給 IP 層最大分段大小,不包含 TCP Header 和 TCP Option,只包含 TCP Payload ,MSS 是 TCP 用來限制應(yīng)用層最大的發(fā)送字節(jié)數(shù)。
假設(shè) MTU= 1500 byte,那么MSS = 1500- 20(IP Header) -20 (TCP Header) = 1460 byte,如果應(yīng)用層有2000 byte發(fā)送,那么需要兩個(gè)切片才可以完成發(fā)送,第一個(gè) TCP 切片 = 1460,第二個(gè) TCP 切片 = 540。


MSS分段 如何查看MSS?

我們都知道TCP三次握手,而MSS會(huì)在三次握手的過程中傳遞給對(duì)方,用于通知對(duì)端本地最大可以接收的TCP報(bào)文數(shù)據(jù)大?。ú话琓CP和IP報(bào)文首部)。

抓包mss

比如上圖中,B將自己的MSS發(fā)送給A,建議A在發(fā)數(shù)據(jù)給B的時(shí)候,采用MSS=1420進(jìn)行分段。而B在發(fā)數(shù)據(jù)給A的時(shí)候,同樣會(huì)帶上MSS=1372。兩者在對(duì)比后,會(huì)采用小的那個(gè)值(1372)作為通信的MSS值,這個(gè)過程叫MSS協(xié)商。

另外,一般情況下MSS + 20(TCP頭)+ 20(IP頭)= MTU,上面抓包的圖里對(duì)應(yīng)的MTU分別是1372+40 和 1420+40。同一個(gè)路徑上,MTU不一定是對(duì)稱的,也就是說A到B和B到A,兩條路徑上的MTU可以是不同的,對(duì)應(yīng)的MSS也一樣。
三次握手中協(xié)商了MSS就不會(huì)改變了嗎?

當(dāng)然不是,每次執(zhí)行TCP發(fā)送消息的函數(shù)時(shí),會(huì)重新計(jì)算一次MSS,再進(jìn)行分段操作。

對(duì)端不傳MSS會(huì)怎么樣?

我們?cè)倏碩CP的報(bào)頭。


TCP報(bào)頭

其實(shí)MSS是作為可選項(xiàng)引入的,只不過一般情況下MSS都會(huì)傳,但是萬(wàn)一遇到了哪臺(tái)機(jī)器的實(shí)現(xiàn)上比較調(diào)皮,不傳MSS這個(gè)可選項(xiàng)。那對(duì)端該怎么辦?

如果沒有接收到對(duì)端TCP的MSS,本端TCP默認(rèn)采用MSS=536Byte

那為什么會(huì)是536?

536(data) + 20(tcp頭)+20(ip頭)= 576Byte

前面提到了IP會(huì)切片,那會(huì)切片,也就會(huì)重組,而這個(gè)576正好是 IP 最小重組緩沖區(qū)的大小。

MTU是什么

MTU: Maximum Transmit Unit,最大傳輸單元。其實(shí)這個(gè)是由數(shù)據(jù)鏈路層提供,為了告訴上層IP層,自己的傳輸能力是多大。IP層就會(huì)根據(jù)它進(jìn)行數(shù)據(jù)包切分。一般 MTU=1500 Byte。
假設(shè)IP層有 <=1500byte 需要發(fā)送,只需要一個(gè) IP 包就可以完成發(fā)送任務(wù);假設(shè) IP 層有 >1500byte 數(shù)據(jù)需要發(fā)送,需要分片才能完成發(fā)送,分片后的 IP Header ID 相同,同時(shí)為了分片后能在接收端把切片組裝起來,還需要在分片后的IP包里加上各種信息。比如這個(gè)分片在原來的IP包里的偏移offset。


MTU分片 如何查看MTU

mac控制臺(tái)輸入ifconfig命令,可以看到MTU的值為多大。

$ ipconfig
lo0: flags=8049 mtu 16384
en0: flags=8863 mtu 1500
p2p0: flags=8843 mtu 2304

可以看到這上面有好幾個(gè)MTU,可以簡(jiǎn)單理解為每個(gè)網(wǎng)卡的處理能力不同,所以對(duì)應(yīng)的MTU也不同。當(dāng)然這個(gè)值是可以修改的,但不在今天的討論范疇內(nèi),不再展開。

在一臺(tái)機(jī)器的應(yīng)用層到這臺(tái)機(jī)器的網(wǎng)卡,這條鏈路上,基本上可以保證,MSS < MTU


MSS和MTU的區(qū)別 為什么MTU一般是1500

這其實(shí)是由傳輸效率決定的。首先,雖然我們平時(shí)用的網(wǎng)絡(luò)感覺挺穩(wěn)定的,但其實(shí)這是因?yàn)門CP在背地里做了各種重傳等保證了傳輸?shù)目煽?,其?shí)背地里線路是動(dòng)不動(dòng)就丟包的,而越大的包,發(fā)生丟包的概率就越大。

那是不是包越小就越好?也不是

但是如果選擇一個(gè)比較小的長(zhǎng)度,假設(shè)選擇MTU300Byte,TCP payload = 300 - IP Header - TCP Header = 300 - 20 - 20 = 260 byte。那有效傳輸效率= 260 / 300 = 86%

而如果以太網(wǎng)長(zhǎng)度為1500,那有效傳輸效率= 1460 / 1500 = 96%,顯然比86%高多了。

所以,包越小越不容易丟包,包越大,傳輸效率又越高,因此權(quán)衡之下,選了1500。

為什么IP層會(huì)分片,TCP還要分段

由于本身IP層就會(huì)做分片這件事情。就算TCP不分段,到了IP層,數(shù)據(jù)包也會(huì)被分片,數(shù)據(jù)也能正常傳輸。

既然網(wǎng)絡(luò)層就會(huì)分片了,那么TCP為什么還要分段?是不是有些多此一舉?

假設(shè)有一份數(shù)據(jù),較大,且在TCP層不分段,如果這份數(shù)據(jù)在發(fā)送的過程中出現(xiàn)丟包現(xiàn)象,TCP會(huì)發(fā)生重傳,那么重傳的就是這一大份數(shù)據(jù)(雖然IP層會(huì)把數(shù)據(jù)切分為MTU長(zhǎng)度的N多個(gè)小包,但是TCP重傳的單位卻是那一大份數(shù)據(jù))。


假設(shè)TCP不分段

如果TCP把這份數(shù)據(jù),分段為N個(gè)小于等于MSS長(zhǎng)度的數(shù)據(jù)包,到了IP層后加上IP頭和TCP頭,還是小于MTU,那么IP層也不會(huì)再進(jìn)行分包。此時(shí)在傳輸路上發(fā)生了丟包,那么TCP重傳的時(shí)候也只是重傳那一小部分的MSS段。效率會(huì)比TCP不分段時(shí)更高。


假設(shè)TCP分段

類似的,傳輸層除了TCP外,還有UDP協(xié)議,但UDP本身不會(huì)分段,所以當(dāng)數(shù)據(jù)量較大時(shí),只能交給IP層去分片,然后傳到底層進(jìn)行發(fā)送。

也就是說,正常情況下,在一臺(tái)機(jī)器的傳輸層到網(wǎng)絡(luò)層這條鏈路上,如果傳輸層對(duì)數(shù)據(jù)做了分段,那么IP層就不會(huì)再分片。如果傳輸層沒分段,那么IP層就可能會(huì)進(jìn)行分片。

說白了,數(shù)據(jù)在TCP分段,就是為了在IP層不需要分片,同時(shí)發(fā)生重傳的時(shí)候只重傳分段后的小份數(shù)據(jù)。

TCP分段了,IP層就一定不會(huì)分片了嗎

上面提到了,在發(fā)送端,TCP分段后,IP層就不會(huì)再分片了。

但是整個(gè)傳輸鏈路中,可能還會(huì)有其他網(wǎng)絡(luò)層設(shè)備,而這些設(shè)備的MTU可能小于發(fā)送端的MTU。此時(shí)雖然數(shù)據(jù)包在發(fā)送端已經(jīng)分段過了,但是在IP層就還會(huì)再分片一次。

如果鏈路上還有設(shè)備有更小的MTU,那么還會(huì)再分片,最后所有的分片都會(huì)在接收端處進(jìn)行組裝。


IP分片再分片

因此,就算TCP分段過后,在鏈路上的其他節(jié)點(diǎn)的IP層也是有可能再分片的,而且哪怕數(shù)據(jù)被第一次IP分片過了,也是有可能被其他機(jī)器的IP層進(jìn)行二次、三次、四次….分片的。

IP層怎么做到不分片

上面提到的IP層在傳輸過程中因?yàn)楦鱾€(gè)節(jié)點(diǎn)間MTU可能不同,導(dǎo)致數(shù)據(jù)是可能被多次分片的。而且每次分片都要加上各種信息便于在接收端進(jìn)行分片重組。那么IP層是否可以做到不分片?

如果有辦法知道整個(gè)鏈路上,最小的MTU是多少,并且以最小MTU長(zhǎng)度發(fā)送數(shù)據(jù),那么不管數(shù)據(jù)傳到哪個(gè)節(jié)點(diǎn),都不會(huì)發(fā)生分片。

整個(gè)鏈路上,最小的MTU,就叫PMTU(path MTU)。

有一個(gè)獲得這個(gè)PMTU的方法,叫 Path MTU Discovery。

$cat /proc/sys/net/ipv4/ip_no_pmtu_disc
0

默認(rèn)為0,意思是開啟PMTU發(fā)現(xiàn)的功能?,F(xiàn)在一般機(jī)器上都是開啟的狀態(tài)。

原理比較簡(jiǎn)單,首先我們先回去看下IP的數(shù)據(jù)報(bào)頭。


IP報(bào)頭DF

這里有個(gè)標(biāo)紅的標(biāo)志位DF(Don't Fragment),當(dāng)它置為1,意味著這個(gè)IP報(bào)文不分片。

當(dāng)鏈路上某個(gè)路由器,收到了這個(gè)報(bào)文,當(dāng)IP報(bào)文長(zhǎng)度大于路由器的MTU時(shí),路由器會(huì)看下這個(gè)IP報(bào)文的DF

  • 如果為0(允許分片),就會(huì)分片并把分片后的數(shù)據(jù)傳到下一個(gè)路由器

  • 如果為1,就會(huì)把數(shù)據(jù)丟棄,同時(shí)返回一個(gè)ICMP包給發(fā)送端,并告訴它"達(dá)咩!"數(shù)據(jù)不可達(dá),需要分片,同時(shí)帶上當(dāng)前機(jī)器的MTU

理解了上面的原理后,我們?cè)倏聪翽MTU發(fā)現(xiàn)是怎么實(shí)現(xiàn)的。

  • 應(yīng)用通過TCP正常發(fā)送消息,傳輸層TCP分段后,到網(wǎng)絡(luò)層加上IP頭,DF置為1,消息再到更底層執(zhí)行發(fā)送

  • 此時(shí)鏈路上有臺(tái)路由器由于各種原因MTU變小了

  • IP消息到這臺(tái)路由器了,路由器發(fā)現(xiàn)消息長(zhǎng)度大于自己的MTU,且消息自帶DF不讓分片。就把消息丟棄。同時(shí)返回一個(gè)ICMP錯(cuò)誤給發(fā)送端,同時(shí)帶上自己的MTU

獲得pmtu
  • 發(fā)送端收到這個(gè)ICMP消息,會(huì)更新自己的MTU,同時(shí)記錄到一個(gè)PMTU表中。

  • 因?yàn)門CP的可靠性,會(huì)嘗試重傳這個(gè)消息,同時(shí)以這個(gè)新MTU值計(jì)算出MSS進(jìn)行分段,此時(shí)新的IP包就可以順利被剛才的路由器轉(zhuǎn)發(fā)。

  • 如果路徑上還有更小的MTU的路由器,那上面發(fā)生的事情還會(huì)再發(fā)生一次。

獲得pmtu后的TCP重傳 總結(jié)
  • 數(shù)據(jù)在TCP分段,在IP層就不需要分片,同時(shí)發(fā)生重傳的時(shí)候只重傳分段后的小份數(shù)據(jù)

  • TCP分段時(shí)使用MSS,IP分片時(shí)使用MTU

  • MSS是通過MTU計(jì)算得到,在三次握手和發(fā)送消息時(shí)都有可能產(chǎn)生變化。

  • IP分片是不得已的行為,盡量不在IP層分片,尤其是鏈路上中間設(shè)備的IP分片。因此,在IPv6中已經(jīng)禁止中間節(jié)點(diǎn)設(shè)備對(duì)IP報(bào)文進(jìn)行分片,分片只能在鏈路的最開頭和最末尾兩端進(jìn)行。

  • 建立連接后,路徑上節(jié)點(diǎn)的MTU值改變時(shí),可以通過PMTU發(fā)現(xiàn)更新發(fā)送端MTU的值。這種情況下,PMTU發(fā)現(xiàn)通過浪費(fèi)N次發(fā)送機(jī)會(huì)來?yè)Q取的PMTU,TCP因?yàn)橛兄貍骺梢员WC可靠性,在UDP就相當(dāng)于消息直接丟了。

文章推薦:









最后

畫動(dòng)圖,太難了。。??赐昵髠€(gè)贊,下次圖會(huì)動(dòng)得更兇。

歡迎大家加我微信(公眾號(hào)里右下角“聯(lián)系我”),互相圍觀朋友圈砍一刀啥的哈哈。


如果文章對(duì)你有幫助,看下文章底部右下角,做點(diǎn)正能量的事情(點(diǎn)兩下)支持一下。(瘋狂暗示,拜托拜托,這對(duì)我真的很重要!

我是小白,我們下期見。

別說了,一起在知識(shí)的海洋里嗆水吧

關(guān)注公眾號(hào):【golang小白成長(zhǎng)記】

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
TCP/IP網(wǎng)絡(luò)模型是怎樣的?
IP分片淺析
《網(wǎng)絡(luò)協(xié)議》IP 分片與 TCP 分段
切,老掉牙的TCP知識(shí)
TCP中的MSS解讀
TCP segment of a reassembled PDU
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服