電腦網路那些事之 MTU 篇

来源:https://www.cnblogs.com/edisonfish/archive/2023/06/27/17509737.html
-Advertisement-
Play Games

哈嘍大家好,我是鹹魚 今天我們來聊聊電腦網路中的 MTU (Maximum Transmission Unit) 什麼是 MTU ? MTU(Maximum Transmission Unit)是指數據鏈路層中的最大傳輸單元 通俗點來講,MTU 是指數據鏈路層能夠傳輸的最大數據幀的大小(以位元組為單 ...


哈嘍大家好,我是鹹魚

 

今天我們來聊聊電腦網路中的 MTU (Maximum Transmission Unit)

 

什麼是 MTU ?

MTU(Maximum Transmission Unit)是指數據鏈路層中的最大傳輸單元

 

通俗點來講,MTU 是指數據鏈路層能夠傳輸的最大數據幀的大小(以位元組為單位)

 以 CentOS 7 為例,可以通過 ifconfig 命令來查看 MTU 值

 

為什麼需要 MTU ?

我們知道,數據在數據鏈路層中通常是以數據幀(Frame)的形式來傳輸

 

因為傳輸的 Frame 不可能無限大(傳小的可以),那麼一次傳多大的 Frame 最合適、最高效就成了一個需要考慮的問題

 

所以說我們要設定一個值(也就是 MTU),這個值用來限制 Frame 的大小

 

維基百科有這麼一段話

 

Larger MTU is associated with reduced overhead. Smaller MTU values can reduce network delay.

 

由上面的話可以得出:

  • MTU越大,開銷越小

這句話是很容易理解的,更大的 Frame 意味著包含的有效數據也就更多

 

我一次能傳更多的數據了,那麼傳輸次數就少了,在網路上的開銷就變小了

 

  • 較小的MTU值可以減少網路延遲

這句話容易讓人引起困惑,為什麼 MTU 值小能夠減少網路延遲呢?

 

如果 MTU 設置的很大,意味著一次能傳更大的數據了,那占據鏈路的時間就會更長,所以總體上網路延遲就會變大

 

而且如果一大段數據裡面有一個 bit 出錯了,這一大段就會整個重傳,重傳的代價是很大的

 

那麼 MTU 設置成多少合適呢?

 

為什麼 MTU 的值是 1500?

RFC 標准定義乙太網的預設 MTU 值為 1500,為什麼是 1500 ?

 

這是一個歷史遺留問題

 

早期的乙太網使用共用鏈路的工作方式,為了保證 CSMA/CD(載波多路復用/衝突檢測)機制,規定了以太幀長度最小為 64 位元組,最大為 1518 位元組

 

  • 最小 64 位元組是為了保證最極端的衝突能被檢測到,64 位元組是能被檢測到的最小值

  • 最大不超過 1518 位元組是為了防止過長的幀傳輸時間過長而占用共用鏈路太長時間導致其他業務阻塞

 

所以說數據幀的最大長度被限製為 1518 位元組(包括幀頭、幀尾和CRC校驗)

 

 

18 位元組用於幀頭和幀尾,其中 CRC 校驗占據 4 位元組,剩下的 1500 位元組就是最大數據載荷(Payload)

 

因此,1500 位元組被定義為乙太網數據幀中數據部分的最大長度(MTU)

 

雖然技術不斷發展,但這個規定一直沒有更改

 

乙太網經過幾十年的發展,速度已經從最初的10M被提升到了上百G,速度提高了上萬倍

 

在這樣高速度的傳輸數據中,如果還是延續經典乙太網的最大幀長不超過1518 位元組的限制,那麼在每秒中傳輸的數據包的個數將很大

 

於是一些廠商提出了巨型幀(Jumbo Frame)的概念,把乙太網的最大幀長擴展到了9K

 

目前還沒有獲得 IEEE 標準委員會的認可,但是大多數的設備廠商都已經開始支持

 

發送數據大小超過 MTU 怎麼辦?

乙太網的 MTU 預設值是 1500,如果發送 Frame 小於 MTU(例如 1000 位元組),直接傳輸就行

 

如果大於 MTU(4000 位元組),那就需要進行分片(Fragment)

 

即第一次發送 1500 位元組(IP header 20 位元組 + Payload 1480 位元組)

 

第二次發送 1500 位元組(IP header 20 位元組 + Payload 1480 位元組)

 

第三次 1000 位元組(IP header 20 位元組 + Payload 980 位元組)

 

 

可能有小伙伴問,那我傳的數據大小不夠數據幀規定的最小 64 位元組怎麼辦?

 

答案是:在實際數據內容後面添加填充數據,使得數據包總長度達到最小長度要求。填充數據可以是任意無意義的位元組,例如全 0 或全 1 的數據

 

如何保證發送的數據不超過 MTU ?

前面我們知道,如果發送的數據大於 MTU,則就會進行分片操作

 

要讓最終傳給數據鏈路層的 Frame 數據大小不超過 1500 bytes,就要保證上層中的每一層的數據都沒有超過這個大小

 

如果 MTU 是 1500,那麼 IP 層就要保證 IP 層的 Packet 數據不超過 1480 bytes (1500 bytes – 20 bytes IP header),

 

對於 TCP 來說,它要保證每一個 Segment 數據大小不超過 1460 bytes (1460 bytes – 20 TCP header)

 

以 TCP 層(傳輸層)為例子, TCP 層是怎麼知道發送的數據不會超過 MTU 呢?

  1. IP 層(網路層)問數據鏈路層數據最大傳輸單元( MTU )是多少

  2. TCP 層會問 IP 層數據最大傳輸大小(Maximum packet size)是多少

 

這樣 TCP 層就會知道自己的最大傳輸數據大小,叫做 MSS(Maximum segment size)

 

在 TCP 的握手階段,MSS(Maximum Segment Size)是用於指定TCP報文段中數據部分的最大長度

 

對於 TCP 來說,知道自己的 MSS 沒有什麼用

 

例如作為接收端來說,收到的包大小取決於發送端,得讓發送端知道自己的 MSS 才行

 

所以在建立 TCP 連接時,雙方需要協商一個合適的 MSS 值,以便在數據傳輸過程中進行分片和重組

 

什麼是 TSO

前面我們介紹了什麼是 MTU、MSS

 

如果你去抓一下包看看,你可能會遇到下麵這種情況

 

明明協商了 MSS 為 1460 位元組,為什麼數據居然有一萬多位元組?

 

在建立 TCP 連接時,雙方需要協商一個合適的 MSS 值,以便在數據傳輸過程中進行分片

 

但是這個分片過程往往是簡單重覆而且計算量比較大的,需要占用較多的 CPU 資源

 

所以網卡就會對內核說:哥這種小事我來乾就好了,不需要麻煩您

 

然後內核就會把大包發給網卡,網卡來負責分片

 

這個叫做 TSO(TCP Segment Offload)

 

TSO(TCP Segmentation Offload)是一種網路傳輸卸載技術,用於減輕主機的網路數據包分段負擔,提高網路傳輸性能

 

我們在抓包的時候看到是還在內核里的包,後面網卡拆包的過程是看不到的

 

網卡不但能對發送的包進行 offload,也可以對接收的包進行 onload,簡單來說就是網卡會先把一些小的包積攢下來,然後合起來發送給內核

 

# 查看網卡上面是否開啟 TSO 功能
# on 表示開啟
[root@root~]# ethtool -k <網卡名稱>
tcp-segmentation-offload: on
      tx-tcp-segmentation: on
      tx-tcp-ecn-segmentation: on
      tx-tcp6-segmentation: on
      tx-tcp-mangleid-segmentation: off

 

最後總結一下:

 

 

    • MTU 是指數據鏈路層能夠傳輸的最大數據幀的大小(以位元組為單位)。由於歷史原因,MTU 的值最小為 64 位元組,最大為 1518 位元組(Payload 則是 46~1500 位元組)

    • 如果發送的數據大於 MTU,則就會進行分片操作;如果小於 MTU,就會在實際數據內容後面添加填充數據,使得數據包總長度達到最小長度要求

    • MSS(Maximum Segment Size)是用於指定 TCP 報文段中數據部分的最大長度。在建立 TCP 連接時,雙方需要協商一個合適的 MSS 值以便在數據傳輸過程中進行分片和重組

    • TSO(TCP Segmentation Offload)是一種網路傳輸卸載技術。TSO 技術將分片過程從 CPU 轉移到網卡上的專用硬體,網卡負責將應用程式的大塊數據分段為適當大小的數據包,並添加 TCP 首部,然後直接發送到網路上


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # 關於EF Core更新速度隨時間越來越慢的解決辦法 ## 概要 本篇主要介紹使用 `context.ChangeTracker.Clear() `方法,在通過迴圈進行批量更新時,通過手動清除跟蹤實體以提高性能的示例。 ## 背景 最近在做一些數據分析時,遇到了一個問題,當我把計算結果更新到資料庫 ...
  • 最早開發Admin 管理插件,是為了微服務節點,有可視化的界面,後續隨著優化開發,豐富了其它功能。目前任意 .Net 或.Net Core的項目,只要在Nuget 中引用 Taurus,即可享有以下管理後臺功能:1、微服務節點管理。2、系統環境信息管理。3、指標統計管理。4、系統配置管理。5、系統日... ...
  • @[TOC](目錄) # 前言 我們可以將設備上行數據存儲到關係型資料庫中,我們需要兩張帶有時間戳的表(**最新數據表** 和 **歷史數據表**),**歷史數據表**存儲所有設備上報的數據,**最新數據表**需要存儲設備最新一條上報數據,這條最新數據相當於設備的當前狀態。然後展示的時候只展示最新一 ...
  • ## 一:背景 ### 1. 講故事 有很多朋友跟我說,在 Windows 上看過你文章知道了怎麼抓 Crash, CPU爆高,記憶體暴漲 等各種Dump,為什麼你沒有寫在 Docker 中如何抓的相關文章呢?瞧不上嗎? 哈哈,在DUMP的分析旅程中,跑在 Docker 中的 .NET 占比真的不多, ...
  • 依賴註入(DI)在開發中既是常見的也是必需的技術。它幫助我們優化了代碼結構,使得應用更加靈活、易於擴展,同時也降低了各個模塊之間的耦合度,更容易進行單元測試,提高了編碼效率和質量。我們經常會先定義局部變數,再在構造函數中使用,每次都要這樣去編寫耗時,下麵通過VS自帶功能,可以給我方便的生成,節省時間... ...
  • 在日常的工作生產中,經常會有將將生產數據或者一些信息主動推送給相關的管理人員,我們公司在開發WMS系統時,為了倉庫的儲存安全,需要在危廢品庫存達到一定的儲量時,自動通知倉管員去處理危廢品,所以就需要程式自動的通過企業微信告知倉管員,這個時候就需要用到企業微信的機器人了。 現在我所知道的企業微信機器人 ...
  • 在 Linux 系統下開發軟體,輸出的可執行文件可大可小,運行環境如果是在伺服器那麼可能資源比較充足,但如果是在嵌入式環境,那麼存儲資源是寸土必爭的。所以會有對可執行文件進行瘦身的需求,比如使用指令 strip。 ...
  • Ubuntu系統開機後總是提示“不完整語言支持”是一個存在已久的bug,一直未被修複,表現為點擊如圖所示更新信息中的“現在執行此動作”並不會安裝任何組件,每次開機自檢後都會提示。 ![](https://img2023.cnblogs.com/blog/3206341/202306/3206341- ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...