首頁  >  文章  >  系統教程  >  簡述Linux系統收發網路封包的過程

簡述Linux系統收發網路封包的過程

WBOY
WBOY轉載
2024-02-12 21:54:33640瀏覽

Linux 伺服器收到網路封包,需要經過哪些處理,一步一步將資料傳給應用程式的呢?當應用程式發送封包時,Linux 又是如何操作將封包傳送出去的呢?今天我們就來聊聊這個話題。

在準備好接收網路封包之前,Linux需要做很多準備工作,例如:網路子系統的初始化、協定堆疊的註冊、網路卡驅動的初始化、啟動網路卡等等,只有這些都準備好了之後,才能真正開始接收網路包。

網路協定堆疊


#在介紹Linux收發網路封包之前,我們先來了解Linux網路協定堆疊。

國際標準化組織制定了開放式系統互聯通訊參考模型(Open System Interconnection Reference Model),也就是OSI 網路模型,該模型主要有7 層,分別是應用層、表示層、會話層、傳輸層、網路層、資料鏈結層以及實體層。

由於 OSI 模型太複雜,提出的只是存在於概念和理論上的一種模型,分層太多,增加了網路工作的複雜性,所以沒有大規模應用。
我們比較常見是TCP/IP 網路模型,Linux 系統正是依照這套網路模型來實現網路協定棧的。

TCP/IP 網路模型共有 4 層,分別是應用層、傳輸層、網路層和網路介面層,每一層負責的功能如下:

1、應用層 對應於OSI參考模型的高層,為使用者提供所需的各種服務,例如:FTP、Telnet、DNS、SMTP等.

2、傳輸層 對應OSI參考模型的傳輸層,為應用層實體提供端對端的通訊功能,保證了封包的順序傳送及資料的完整性。此層定義了兩個主要的協定:傳輸控制協定(TCP)和用戶資料報協定(UDP).

3、網路層 對應OSI參考模型的網路層,主要解決主機到主機的通訊問題。它所包含的協定設計資料包在整個網路上的邏輯傳輸。專注於重新賦予主機一個IP位址來完成對主機的尋址,它也負責資料包在多種網路中的路由。此層有三個主要協定:網際協定(IP)、網際網路群組管理協定(IGMP)和網際網路控制封包協定(ICMP)。

4、網路介面層 與OSI參考模型中的實體層與資料鏈結層相對應。它負責監視資料在主機和網路之間的交換。事實上,TCP/IP本身並未定義該層的協議,而由參與互連的各網路使用自己的實體層和資料鏈結層協議,然後與TCP/IP的網路存取層進行連接。位址解析協定(ARP)工作在此層,即OSI參考模型的資料鏈結層。
簡述Linux系統收發網路封包的過程

#接收網路封包


簡述Linux系統收發網路封包的過程

#網路封包到達網卡後,依照FIFO順序存入網卡的接收佇列,網卡透過 DMA 技術,將網路封包寫入指定的記憶體位址(Ring Buffer)。

Ring Buffer是在網卡驅動程式啟動時建立和初始化的,儲存的是sk_buff緩衝區的描述符(物理位址和大小等)。

#

當網路包到達時,從Ring Buffer取得指向的sk_buff描述符,透過DMA將資料寫入該位址。等sk_buff中的資料交由上層協定棧處理後,Ring Buffer中的描述更新為新分配的sk_buff。

#接著網路卡向 CPU 發起硬體中斷,當 CPU 收到硬體中斷要求後,根據中斷註冊表,找到註冊的中斷處理函數。

硬體中斷處理函數會做如下的事情:

1、屏蔽網卡的中斷

#目的是避免CPU被頻繁中斷而無法處理其他任務,屏蔽中斷是告訴網卡已經知道記憶體中有資料了,下次再收到資料包直接寫記憶體就可以了,不要再通知 CPU 了。

#2、發起軟體中斷,恢復剛才屏蔽的中斷

#「

#內核中的ksoftirqd 線程收到軟中斷後,就會調用相應軟中斷的處理函數來輪詢處理數據,即:從Ring Buffer 中獲取一個數據幀,用sk_buff 表示,作為一個網絡包交給網路協定棧從下到上進行逐層處理。

#網路協定堆疊對網路套件的處理流程如下:

#1、網路介面層

#「

#首先,網路介面層檢查封包的合法性和正確性,如果不合法或封包校驗不正確則丟棄,否則找出上層協定的類型(IPv4還是IPv6),去掉幀頭、幀尾,然後交給上層即網絡層處理。

#2、網路層

#「

#網路層取出IP頭,判斷網路包下一步的走向,是轉送還是交給上層。當確認網路包是要傳送給本機後,就取出上層協定的類型(例如TCP或UDP),去掉IP頭,然後交給傳輸層處理。

#3、傳輸層

#「

#傳輸層取出 TCP 頭或 UDP 頭後,根據四元組【 來源 IP、來源連接埠、目的 IP、目的連接埠 】,找出對應的 Socket,並把資料拷貝到 Socket 的接收緩衝區。

#4、應用層

#「

#最後,應用層程式呼叫 Socket 接口,將內核的 Socket 接收緩衝區的資料拷貝到應用層的緩衝區。

#到這裡,一個網路包的接收過程就結束了。

發送網路封包


#我們了解網路包的接收流程後,就很容易了解網路包的發送流程了。網路包的發送方向,正好跟接收方向相反。

首先,應用程式呼叫 Socket 發送網路包的介面。這是一個系統調用,會從用戶態陷入到內核態的套接字層。

套接字層會申請一個內核態的 sk_buff 內存,將用戶待發送的資料拷貝到 sk_buff 內存,並將其加入到Socket發送緩衝區等待網路協定棧的處理。

由於網路資料包從應用程式傳到核心時是原始數據,因此協定堆疊要在原始資料中加入通訊約定才能保證資料到達服務端能被正確辨識。網路協定堆疊從Socket 發送緩衝區中,取出資料包,然後依照TCP/IP 棧的分層(傳輸層、網路層、網路介面層),從上到下逐層處理,各層將協定的頭資訊不斷插入到資料包中。

協定堆疊對傳送封包的處理流程如下:

#1、傳輸層

#「

#在傳輸層,會為器添加TCP頭,同時拷貝一個新的sk_buff 副本,這是因為sk_buff 在到達網卡發送完成的時候,會被釋放掉,而TCP 協議是支援重傳的,為確保網路包可靠傳輸,在收到對方的ACK 之前,這個sk_buff 不能被刪除。

#2、網路層

#「

#在網路層,主要會做這些工作:選取路由(確認下一跳的 IP)、填充 IP 頭、netfilter 過濾、對超過 MTU 大小的封包進行分片。處理完這些工作後會交給網路介面層處理。

#3、網路介面層

#「

#

網路介面層會進行實體位址定址,以找到下一跳的 MAC 位址,填入幀頭和幀尾,將其放到傳送佇列中。然後觸發軟中斷告訴網卡驅動程式:佇列中有新的網路包需要發送。驅動程式收到通知會通過 DMA ,從發送包佇列中讀出網路幀,並透過DMA將資料寫入網卡的FIFO發送佇列。

#4、網路卡設備

#「

#網卡設備從FIFO發送隊列中取出資料包,將其發送到網路;當發送完成的時候,網卡設備會觸發一個硬中斷來釋放內存,主要是釋放 sk_buff內存和清理 RingBuffer 內存。最後,當收到這個 TCP 封包的 ACK 應答時,傳輸層就會釋放原始的 sk_buff。

#至此,一個網路包的發送流程就結束了。

以上是簡述Linux系統收發網路封包的過程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:lxlinux.net。如有侵權,請聯絡admin@php.cn刪除