計算機網絡⑩ —— Linux系統如何收發網絡包

  • 轉載于小林coding:https://www.xiaolincoding.com/network/1_base/how_os_deal_network_package.html

1. OSI七層模型

  • 應用層,負責給應用程序提供統一的接口;
  • 表示層,負責把數據轉換成兼容另一個系統能識別的格式;
  • 會話層,負責建立、管理和終止表示層實體之間的通信會話;
  • 傳輸層,負責端到端的數據傳輸;
  • 網絡層,負責數據的路由、轉發、分片;
  • 數據鏈路層,負責數據的封幀和差錯檢測,以及 MAC 尋址;
  • 物理層,負責在物理網絡中傳輸數據幀;- 應用層,負責給應用程序提供統一的接口;

2. 數據傳輸過程

在這里插入圖片描述

  • 傳輸層,給應用數據前面增加了 TCP 頭;
  • 網絡層,給 TCP 數據包前面增加了 IP 頭;
  • 網絡接口層,給 IP 數據包前后分別增加了幀頭和幀尾;
  • 數據鏈路層中并不能傳輸任意大小的數據包,所以在以太網中,規定了最大傳輸單元(MTU)是 1500 字節,也就是規定了單次傳輸的最大 IP 包大小
    • 當網絡包超過 MTU 的大小,就會在網絡層分片,以確保分片后的 IP 包不會超過 MTU 大小
    • 如果 MTU 越小,需要的分包就越多,那么網絡吞吐能力就越差
    • 如果 MTU 越大,需要的分包就越少,那么網絡吞吐能力就越好

3. Linux 網絡協議棧

  • 應用程序需要通過系統調用,來跟 Socket 層進行數據交互;
  • Socket 層的下面就是傳輸層、網絡層和網絡接口層;
  • 最下面的一層,則是網卡驅動程序和硬件網卡設備;

在這里插入圖片描述

4. Linux 接收網絡包的流程

  • 網卡是計算機里的一個硬件,專門負責接收和發送網絡包,當網卡接收到一個網絡包后,會通過 DMA 技術,將網絡包寫入到指定的內存地址,也就是寫入到 Ring Buffer ,這個是一個環形緩沖區,接著就會告訴操作系統這個網絡包已經到達。
  • 告知操作系統網絡包已到達的方式:
    • 觸發中斷:每當網卡收到一個網絡包,就觸發一個中斷告訴操作系統
      • 問題:在高性能網絡場景下,網絡包的數量會非常多,那么就會觸發非常多的中斷,CPU收到中斷后會先去處理這件事,因此會影響系統的整體性能
    • NAPI機制:混合「中斷和輪詢」的方式來接收網絡包,當有網絡包到達時,會通過 DMA 技術,將網絡包寫入到指定的內存地址,接著網卡向 CPU 發起硬件中斷,當 CPU 收到硬件中斷請求后,根據中斷表,調用已經注冊的中斷處理函數。
      • 中斷處理函數:
        • 先「暫時屏蔽中斷」,表示已經知道內存中有數據了,告訴網卡下次再收到數據包直接寫內存就可以了,不要再通知 CPU 了,這樣可以提高效率,避免 CPU 不停的被中斷。
        • 接著,發起「軟中斷」,然后恢復剛才屏蔽的中斷。
      • 軟中斷:內核中的 ksoftirqd 線程專門負責軟中斷的處理,當 ksoftirqd 內核線程收到軟中斷后,就會來輪詢處理數據(采用poll方法)。
        • ksoftirqd 線程會從 Ring Buffer 中獲取一個數據幀,用 sk_buff 表示,從而可以作為一個網絡包交給網絡協議棧進行逐層處理。
      • 網絡協議棧:
        • 先進入到網絡接口層,在這一層會檢查報文的合法性,如果不合法則丟棄,合法則會找出該網絡包的上層協議的類型,比如是 IPv4,還是 IPv6,接著再去掉幀頭和幀尾,然后交給網絡層。
        • 網絡層,則取出 IP 包,判斷網絡包下一步的走向,比如是交給上層處理還是轉發出去。當確認這個網絡包要發送給本機后,就會從 IP 頭里看看上一層協議的類型是 TCP 還是 UDP,接著去掉 IP 頭,然后交給傳輸層。
        • 傳輸層取出 TCP 頭或 UDP 頭,根據四元組「源 IP、源端口、目的 IP、目的端口」 作為標識,找出對應的 Socket,并把數據放到 Socket 的接收緩沖區。
        • 應用層程序調用 Socket 接口,將內核的 Socket 接收緩沖區的數據「拷貝」到應用層的緩沖區,然后喚醒用戶進程。

在這里插入圖片描述

5. Linux 發送網絡包的流程

  • 首先,應用程序會調用 Socket 發送數據包的接口,由于這個是系統調用,所以會從用戶態陷入到內核態中的 Socket 層,內核會申請一個內核態的 sk_buff 內存,將用戶待發送的數據拷貝到 sk_buff 內存,并將其加入到發送緩沖區
  • 接下來,網絡協議棧從 Socket 發送緩沖區中取出 sk_buff,并按照 TCP/IP 協議棧從上到下逐層處理。
    • 如果使用的是 TCP 傳輸協議發送數據,那么先拷貝一個新的 sk_buff 副本,因為 sk_buff 后續在調用網絡層,最后到達網卡發送完成的時候,這個 sk_buff 會被釋放掉。而 TCP 協議是支持丟失重傳的,在收到對方的 ACK 之前,這個 sk_buff 不能被刪除。所以內核的做法就是每次調用網卡發送的時候,實際上傳遞出去的是 sk_buff 的一個拷貝,等收到 ACK 再真正刪除。
    • 接著,對 sk_buff 填充 TCP 頭。sk_buff 可以表示各個層的數據包,在應用層數據包叫 data,在 TCP 層我們稱為 segment,在 IP 層我們叫 packet,在數據鏈路層稱為 frame。
      • 全部數據包只用一個結構體來描述是因為:協議棧采用的是分層結構,上層向下層傳遞數據時需要增加包頭,下層向上層數據時又需要去掉包頭,如果每一層都用一個結構體,那在層之間傳遞數據的時候,就要發生多次拷貝,這將大大降低 CPU 效率。
      • 只用 sk_buff 一個結構體來描述所有的網絡包不會發生拷貝,通過調整 sk_buff 中 data 的指針來實現,比如:
        • 當接收報文時,從網卡驅動開始,通過協議棧層層往上傳送數據報,通過增加 skb->data 的值,來逐步剝離協議首部。
          • 當要發送報文時,創建 sk_buff 結構體,數據緩存區的頭部預留足夠的空間,用來填充各層首部,在經過各下層協議時,通過減少 skb->data 的值來增加協議首部。

在這里插入圖片描述

  • 到達網絡層的主要工作:選取路由(確認下一跳的 IP)、填充 IP 頭、netfilter 過濾、對超過 MTU 大小的數據包進行分片。處理完這些工作后會交給網絡接口層處理。

    • 網絡接口層會通過 ARP 協議獲得下一跳的 MAC 地址,然后對 sk_buff 填充幀頭和幀尾,接著將 sk_buff 放到網卡的發送隊列中。
    • 這一些工作準備好后,會觸發「軟中斷」告訴網卡驅動程序,這里有新的網絡包需要發送,驅動程序會從發送隊列中讀取 sk_buff,將這個 sk_buff 掛到 RingBuffer 中,接著將 sk_buff 數據映射到網卡可訪問的內存 DMA 區域,最后觸發真實的發送。
    • 當發送完成的時候,網卡設備會觸發一個硬中斷來釋放內存,主要是釋放 sk_buff 內存和清理 RingBuffer 內存。
    • 最后,當收到這個 TCP 報文的 ACK 應答時,傳輸層就會釋放原始的 sk_buff 。
  • 問題:發送網絡數據的時候,涉及幾次內存拷貝操作?

    • 第一次,調用發送數據的系統調用的時候,內核會申請一個內核態的 sk_buff 內存,將用戶待發送的數據拷貝到 sk_buff 內存,并將其加入到發送緩沖區。
    • 第二次,在使用 TCP 傳輸協議的情況下,從傳輸層進入網絡層的時候,每一個 sk_buff 都會被克隆一個新的副本出來。副本 sk_buff 會被送往網絡層,等它發送完的時候就會釋放掉,然后原始的 sk_buff 還保留在傳輸層,目的是為了實現 TCP 的可靠傳輸,等收到這個數據包的 ACK 時,才會釋放原始的 sk_buff 。
    • 第三次,當 IP 層發現 sk_buff 大于 MTU 時才需要進行。會再申請額外的 sk_buff,并將原來的 sk_buff 拷貝為多個小的 sk_buff。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/21654.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/21654.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/21654.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

深度剖析云邊對接技術:探索開放API接口的價值與意義

在當今數字化時代的浪潮中,云邊對接與開放API接口成為了塑造行業生態的重要驅動力。隨著云計算、物聯網和邊緣計算等技術的快速發展,傳統產業正在邁向數字化轉型的關鍵時刻。而在這個過程中,云邊對接技術以及開放的應用程序接口(API)扮演著舉…

處理STM32 DMA方式下的HAL_UART_ERROR_ORE錯誤

1. 檢查并調整DMA和UART配置 確保初始化順序:需要確保USART的CR寄存器UE位開關留到最后打開,即完成USART和DMA的所有配置初始化后再使能USART。這樣可以避免初始化順序不當導致的通信問題。配置合適的DMA緩沖區:確保DMA緩沖區足夠大&#xf…

Facebook海外三不限 | 如何降低Facebook頻繁被封的風險

本文將討論Facebook賬戶被封的原因及降低封禁風險的方法,以維護用戶的賬戶安全和社交樂趣。 1. 常見原因:賬戶被封通常與發布違反社區標準的內容有關,如仇恨言論、暴力內容、欺詐虛假信息、非法活動、騷擾、版權侵權等。此外,未授…

el-date-picker選擇開始日期的近半年

<el-date-pickerv-model"form[val.key]":type"val.datePickerType || daterange":clearable"val.clearable && true"range-separator"~"start-placeholder"開始日期"end-placeholder"結束日期"style&q…

玩轉Linux進度條

準備工作&#xff1a; 一.關于緩沖區 首先&#xff0c;咱們先來一段有意思的代碼&#xff1a; #include<stdio.h> #include<unistd.h> int main() {printf("you can see me");sleep(5);} 你可以在你的本地運行一下&#xff0c;這里我告訴大家運行結果…

【SAP HANA 33】前端參數多選情況下HANA如何使用in來匹配?

場面描述: 在操作界面經常會出現某個文本框需要多選的情況,然后后臺需要根據多選的值進行匹配搜索。 一般處理的情況是: 1、在Java后端動態生成SQL 2、不改變動態SQL的情況,直接當做一個正常的參數進行傳遞 本次方案是第二個,直接當做一個正常的字符串參數進行傳遞即…

【面試題-014】Mysql數據庫有哪些索引類型?

文章目錄 B 樹和 B 樹區別B 樹B 樹 mysql聚簇索引和非聚簇索引聚簇索引&#xff08;Clustered Index&#xff09;非聚簇索引&#xff08;Non-Clustered Index&#xff09;總結 MyISAM和InnoDB兩種常見的存儲引擎區別MySQL的主從同步原理如何確保主從同步的數據一致性&#xff1…

使用C++實現高效的套接字連接池

在現代網絡應用中&#xff0c;高效管理網絡連接是實現高并發和低延遲的重要因素。下面將詳細介紹如何使用C實現一個高效的套接字連接池&#xff0c;以便在需要時快速復用連接&#xff0c;從而提高系統性能和資源利用率。 一、什么是連接池&#xff1f; 連接池是一種管理網絡連…

RFID防盜門:守護您的商品資產安全!

在新零售運營管理中&#xff0c;防盜是至關重要的一環。根據美國零售聯合會發布的年度零售安全調查&#xff0c;2022年美國零售商損失了創紀錄的1121億美元。其中年度損失最大因素是由外部盜竊導致庫存損失和員工內部盜竊造成的。 然而傳統零售業商品資產盤點往往依賴人工排查&…

ConcurrentHashMap詳解 什么時候CAS什么時候synchronized

jdk:1.7 segment數組hashEntry數組鏈表實現 jdk版本&#xff1a;1.8&#xff1a;hashEntry數組紅黑樹實現 1、基本參數 //**1、最大容量** hashmap的最大容量也是這個&#xff0c;菜鳥一面被問到了 private static final int MAXIMUM_CAPACITY 1 << 30;//數組默認為…

《科技與健康》是什么級別的期刊?是正規期刊嗎?能評職稱嗎?

問題解答 問&#xff1a;《科技與健康》期刊萬方網可查嗎 答&#xff1a;萬方、維普可查 問&#xff1a;《科技與健康》是正規期刊嗎&#xff1f; 答&#xff1a;萬方維普收錄的正規期刊。主管單位&#xff1a;長江出版傳媒股份有限公司 主辦單位&#xff1a;湖北科學技術…

孩子出生后為什么要做聽力篩查?

孩子出生后為什么要做聽力篩查&#xff1f; 新生兒聽力篩查&#xff0c;就是對所有新生兒在盡早的時間&#xff08;出生48小時后&#xff09;進行系統的聽力篩查測試。據相關文獻報道&#xff0c;在我國&#xff0c;正常分娩的新生兒聽力障礙的發生率約為0.1&#xff5e;0.3%&a…

機場專用手持激光驅鳥器原理及優勢

在機場的驅鳥工作中&#xff0c;各類驅鳥設備共同構建起一道堅不可摧的防線&#xff0c;以保障航班的安全起降。其中激光驅鳥器以其卓越的性能和顯著效果&#xff0c;在機場鳥擊防治中發揮著至關重要的作用。 激光驅鳥器&#xff0c;分為大型自動式和小型手持式&#xff0c;其有…

Python 技能提升(二)

理想的類結構 Property裝飾器 # 傳統寫法 class Square1:def __init__(self):self.__side Nonedef get_side(self):return self.__sidedef set_side(self, side):assert side > 0, 邊長不能為負數&#xff01;self.__side sidedef del_side(self):# del self.__sideself.…

「前端+鴻蒙」核心技術HTML5+CSS3(十)

1、H5簡介 H5是HTML5的簡稱,是構建現代網站和網絡應用的標準標記語言。HTML5新增了許多功能,包括更好的多媒體支持、新的表單控件、繪圖功能以及對響應式設計的改進。 2、H5產品布局 移動端H5網站布局通常使用流體布局或彈性盒模型(Flexbox),以適應不同屏幕尺寸。 示例…

2024年有什么值得入手的5G長期套餐大流量卡推薦?大流量手機卡入手指南(超4款正規手機卡實測總結)

前言 24年有什么值得入手的5G大流量卡推薦&#xff1f;大流量手機卡入手指南&#xff08;超4款正規手機卡實測總結&#xff09; 四大運營商有哪些大流量卡&#xff0c;可電話&#xff0c;非物聯網卡 所有卡激活后&#xff0c;均可以在官方app可查、 所有都是優惠長期 5G大流…

Python-匿名函數

一、概念 匿名函數造出來的是一個內存地址&#xff0c;且內存地址沒有綁定任何名字&#xff0c;很快被當做垃圾清理掉。所以匿名函數只需要臨時調用一次&#xff0c;而有名函數永久使用&#xff1b; 匿名函數一般和其他函數配合使用&#xff1b; # 有名函數def func(x, y):…

抖音直播統計、直播間無人互動直播效果軟件--抖音大師!

抖音大師介紹 抖音大師是抖音直播統計、直播間無人互動直播效果軟件&#xff0c;通過它&#xff0c;你可以快速添加直播互動效果&#xff01;軟件使用C#開發&#xff0c;無論是內存占用還是執行效果都遠比同行的效果高太多&#xff01;&#xff01;電腦所需性能大大降低&#x…

內聯匯編簡介

在C語言中嵌入匯編&#xff08;Assembly&#xff09;代碼&#xff0c;可以使用內聯匯編&#xff08;Inline Assembly&#xff09;&#xff0c;這在一些需要精確控制硬件或者優化性能的場合非常有用 以下是關于ASM語法的介紹&#xff0c;主要基于GCC&#xff08;GNU Compiler C…

做軟件測試需要懂代碼嗎?

隨著大數據、機器學習時代的到來&#xff0c;不少人有了“測試不需要懂代碼&#xff0c;那我就試試”的想法。這就引發了一系列疑問&#xff1a;不懂代碼可以做測試嗎&#xff1f;測試人員到底需不需要懂代碼&#xff1f;測試人員需要寫代碼嗎&#xff1f; 其實&#xff0c;在…