TCP和1448
1448位元組是實際情境下,單個TCP包的實際運載能力。也就是說,實際情境下,上層調用send(1000KB),下層會把這1000KB封裝成多個TCP包進行發送。單個TCP包每次打包1448位元組的資料進行發送。
詳細的TCP在傳輸情景wireshark截圖如圖1
圖1
每個TCP包在理論上應該能打包更多資料才對,但是實際情境下TCP傳輸為什麼會以這個1448作為打包單位呢。
這個實際TCP單包傳輸1448位元組資料的根源在於“乙太網路Ethernet最大的資料幀是1518位元組”。
1500位元組的MTU
乙太網路Ethernet最大的資料幀是1518位元組。乙太網路幀的幀頭14位元組和幀尾CRC校正4位元組(共佔18位元組),剩下承載上層協議的地方也就是Data域最大就只剩1500位元組. 這個值我們就把它稱之為MTU。
我們來看看linux上MTU預設值,查證一下,如圖2
圖2
這個MTU值可以修改,但是現在大部分電腦網路都被乙太網路承載,所以修改這個值沒有什麼實際意義。
MSS決定TCP的單包傳輸量 MSS就是TCP資料包每次能夠傳輸的最大量。為了達到最佳的傳輸效能, TCP協議在建立串連的時候通常 要協商雙方的MSS值,這個值TCP協議在實現的 時候往往用MTU值代替(需要減去IP資料包包頭的大小20Bytes和TCP資料區段的 包頭 20Bytes )所以往往 MSS 為 1460( 如圖1中紅色方框所示的SYN包中的MSS值)。通訊雙方會根據雙方提供的 MSS 值得最小 值確定為這次串連的最大 MSS 值。 MSS為1460是由1500-20(IP頭)-20(TCP頭)計算出的。
實際情境下,TCP包頭中會帶有12位元組的選項----時間戳記。
這樣,單個TCP包實際傳輸的最大量就縮減為1448位元組。1448=1500-20(IP頭)-32(20位元組TCP頭和12位元組TCP選項時間戳記)
回到我們開篇的問題 “每個TCP包在理論上應該能打包更多資料才對,但是實際情境下TCP傳輸為什麼會以這個1448作為打包單位呢。”
理論上,單個TCP包能打包的資料量遠遠多於1448位元組,現在為了適應MTU,只要在乙太網路上跑TCP,系統就預設最大以1448位元組打包TCP。
假如我們用更大的資料量來打包會有什麼結果呢。
答案是降低了傳輸效率。
超過MTU的大包反而降低效率的原因如下:
IP層非常關心MTU,因為IP層會根據MTU來決定是否把上層傳下來的資料進行分區。就像一條運輸線路的承載能力是有限的,碰到大東西要運輸,只能把大東西拆開成為散件,分開運輸,到達目的地之後還必須能再次組裝起來。 當兩台遠程PC互聯的時候,它們的資料需要穿過很多的路由器和各種各樣的網路媒介才能到達對端,網路中不同媒介的MTU各不相同,就好比一長段的水管,由不同粗細的水管組成(MTU不同 :))通過這段水管最大水量就要由中間最細的水管決定。 對於網路層的上層協議而言(我們以TCP/IP協議族為例)它們對水管粗細不在意它們認為這個是網路層的事情。網路層IP協議會檢查每個從上層協議下來的資料包的大小,並根據本機MTU的大小決定是否作“分區”處理。分區最大的壞處就是降低了傳輸效能,本來一次可以搞定的事情,分成多次搞定,所以在網路層更高一層(就是傳輸層)的實現中往往會對此加以注意。
這個就是在乙太網路上,TCP不發大包,反而發送1448小包的原因。只要這個值TCP才能對鏈路進行效能最高的利用。
轉載地址: http://enyuxuexi.blog.chinaunix.net/uid-29075379-id-3920264.html