TCP/IP 網絡模型
應用層(Application Layer)
應用層只需要專注于為用戶提供應用功能,比如 HTTP、FTP、Telnet、DNS、SMTP等。
應用層是工作在操作系統中的用戶態,傳輸層及以下則工作在內核態。
傳輸層(Transport Layer)
應用層的數據包會傳給傳輸層,傳輸層是為應用層提供網絡支持的。
傳輸層只需要服務好應用即可,它作為應用間數據傳輸的媒介,幫助實現應用到應用的通信,而實際的傳輸功能就交給下一層,也就是網絡層。
TCP
- TCP 的全稱叫傳輸控制協議(Transmission Control Protocol)。大部分應用使用的正是 TCP 傳輸層協議,比如 HTTP 應用層協議。
- TCP 相比 UDP 多了很多特性,比如流量控制、超時重傳、擁塞控制等,這些都是為了保證數據包能可靠地傳輸給對方。
UDP
- UDP全稱叫用戶數據報協議(User Datagram Protocol)。
- UDP 只負責發送數據包,不保證數據包是否能抵達對方,但它實時性相對更好,傳輸效率也高。
TCP 段(TCP Segment)
當傳輸層的數據包大小超過 MSS(TCP 最大報文段長度) ,就要將數據包分塊,這樣即使中途有一個分塊丟失或損壞了,只需要重新發送這一個分塊,而不用重新發送整個數據包,在 TCP 協議中,我們把每個分塊稱為一個 TCP 段。
端口
當設備作為接收方時,傳輸層則要負責把數據包傳給應用,但是一臺設備上可能會有很多應用在接收或者傳輸數據,因此需要用一個編號將應用區分開來,這個編號就是端口。
由于傳輸層的報文中會攜帶端口號,因此接收方可以識別出該報文是發送給哪個應用。
網絡層(Internet Layer)
- 傳輸層只需要服務好應用即可,它作為應用間數據傳輸的媒介,幫助實現應用到應用的通信,而實際的傳輸功能就交給下一層,也就是網絡層。
IP 協議(Internet Protocol)
IP 協議會將傳輸層的報文作為數據部分,再加上 IP 包頭組裝成 IP 報文,如果 IP 報文大小超過 MTU(以太網中一般為 1500 字節)就會再次進行分片,得到一個即將發送到網絡的 IP 報文。
IP 地址
網絡層負責將數據從一個設備傳輸到另一個設備,設備有很多,因此網絡層需要有區分設備的編號,一般用 IP 地址給設備進行編號。
IP 地址分成兩種意義:
- 一個是網絡號,負責標識該 IP 地址是屬于哪個「子網」 的。
- 一個是主機號,負責標識同一「子網」下的不同主機;
在尋址的過程中,先匹配到相同的網絡號(表示要找到同一個子網),才會去找對應的主機。
子網掩碼
需要配合子網掩碼才能算出 IP 地址的網絡號和主機號。
- 比如
10.100.122.0/24
,后面的/24
表示就是255.255.255.0
子網掩碼.- 255.255.255.0 二進制是「11111111-11111111-11111111-00000000」, 24 個1,為了簡化子網掩碼的表示,用
/24
代替255.255.255.0
。
計算網絡地址和主機地址
- 將IP地址和子網掩碼進行按位與運算,就可以得到網絡號。
- 將子網掩碼取反后與IP地址進行進行按位與運算,就可以得到主機號。
路由
- 當數據包到達一個網絡節點,需要通過路由算法決定下一步走哪條路徑。
- 路由器尋址工作中,就是要找到目標地址的子網,找到后進而把數據包轉發給對應的網絡內。
IP尋址 vs 路由
- IP 協議的尋址作用是告訴去往下一個目的地該朝哪個方向走
- 路由則是根據「下一個目的地」選擇路徑
- 尋址更像在導航,路由更像在操作方向盤
網絡接口層(Link Layer)
生成了 IP 頭部之后, 網絡接口層在 IP 頭部的前面加上 MAC 頭部,并封裝成
數據幀(Data frame) 發送到網絡上。
網絡接口層主要為網絡層提供 「鏈路級別」傳輸 的服務,負責在以太網、WiFi 這樣的底層網絡上發送原始數據包,工作在網卡這個層次,使用 MAC 地址來標識網絡上的設備。
以太網
以太網就是一種在「局域網」內,把附近的設備連接起來,使它們之間可以進行通訊的技術。
-
以太網在判斷網絡包目的地時和 IP 的方式不同,必須采用相匹配的方式才能在以太網中將包發往目的地,以太網進行通訊要用到 MAC 地址。
-
MAC 頭部是以太網使用的頭部,它包含了接收方和發送方的 MAC 地址等信息。可以通過 ARP 協議獲取對方的 MAC 地址。
總結
TCP/IP 網絡通常是由上到下分成 4 層,分別是應用層,傳輸層,網絡層和網絡接口層。
每一層的封裝格式
網絡接口層
的傳輸單位是 幀(frame)IP 層
的傳輸單位是 包(packet)TCP 層
的傳輸單位是 段(segment)HTTP
的傳輸單位則是 消息或報文(message)
這些名詞并沒有什么本質的區分,可以統稱為數據包。
HTTP
1. 解析URL
- 瀏覽器做的第一步工作是解析 URL, 從而生成發送給 Web 服務器的請求信息。
- URL 實際上是請求服務器里的文件資源。
2. 生產 HTTP 請求信息
對 URL 進行解析之后,瀏覽器確定了 Web 服務器和文件名,接下來就是根據這些信息來生成 HTTP 請求消息了。
DNS(真實地址查詢)
查詢服務器域名對應的 IP 地址
- 通過瀏覽器解析 URL 并生成 HTTP 消息后,需要委托操作系統將消息發送給 Web 服務器。
委托操作系統發送消息時,必須提供通信對象的 IP 地址。
DNS 服務器,專門保存 Web 服務器域名與 IP 的對應關系。
域名的層級關系
- DNS 中的域名都是用句點來分隔的,比如
www.server.com
,這里的句點代表了不同層次之間的界限, 最后的一個點代表根域名。 - 在域名中,越靠右的位置表示其層級越高。
域名的層級關系類似一個樹狀結構:
- 根 DNS 服務器(.)
- 頂級域 DNS 服務器(.com)
- 權威 DNS 服務器(server.com)
域名解析的工作流程
-
瀏覽器會先看自身有沒有對這個域名的緩存,
- 如果有,就直接返回
- 如果沒有,就去問操作系統
-
操作系統也會去看自己的緩存,
- 如果有,就直接返回
- 如果沒有,再去 hosts 文件看
-
hosts 文件也沒有,才會去問 「本地DNS 服務器」 。
DNS 域名解析的過程,只指路不帶路。
協議棧
通過 DNS 獲取到 IP 后,就可以把 HTTP 的傳輸工作交給操作系統中的協議棧。
IP 中還包括 ICMP 協議和 ARP 協議:
ICMP
用于告知網絡包傳送過程中產生的錯誤以及各種控制信息。ARP
用于根據 IP 地址查詢相應的以太網 MAC 地址。
TCP(可靠傳輸)
HTTP 是基于 TCP 協議傳輸的。
TCP 包頭格式
狀態位:
SYN
是發起一個連接,ACK
是回復,RST
是重新連接,FIN
是結束連接
TCP 三次握手
在 HTTP 傳輸數據之前,首先需要 TCP 建立連接,TCP 連接的建立,通常稱為三次握手。
三次握手目的是保證雙方都有發送和接收的能力。
TCP 連接狀態
TCP 分割數據
TCP 報文生成
TCP 協議里面會有兩個端口,
- 一個是瀏覽器監聽的端口(通常是隨機生成的)
- 一個是 Web 服務器監聽的端口(HTTP 默認端口號是 80, HTTPS 默認端口號是 443)
在雙方建立了連接后,TCP 報文中的數據部分就是存放 HTTP 頭部 + 數據,組裝好 TCP 報文之后,就需交給下面的網絡層處理。
網絡包的報文:
IP (遠程定位)
TCP 模塊在執行連接、收發、斷開等各階段操作時,都需要委托 IP 模塊將數據封裝成網絡包發送給通信對象。
IP包頭格式
IP 頭部的源地址選擇
假設 Web 服務器的目標地址是 192.168.10.200
:
IP 報文生成
MAC(兩點傳輸)
生成了 IP 頭部之后,接下來網絡包還需要在 IP 頭部的前面加上 MAC 頭部。
MAC 包頭格式
MAC 頭部是以太網使用的頭部,它包含了接收方和發送方的 MAC 地址等信息。
一般在 TCP/IP 通信里,MAC 包頭的協議類型只使用:
0800
: IP 協議0806
: ARP 協議
獲取對方的 MAC 地址
需要 ARP 協議幫我們找到路由器的 MAC 地址。
后續操作系統會把本次查詢結果放到一塊叫做 ARP 緩存的內存空間留著以后用,不過緩存的時間就幾分鐘。
MAC 報文生成
網卡(出口)
- 網絡包只是存放在內存中的一串二進制數字信息,沒有辦法直接發送給對方。
- 網卡:負責將數字信息轉換為電信號,使其能在網線上傳輸(真正的數據發送過程)。
- 控制網卡還需要靠網卡驅動程序。
- 網卡驅動獲取網絡包之后,會將其復制到網卡內的緩存區中,接著會在其開頭加上報頭和起始幀分界符,在末尾加上用于檢測錯誤的幀校驗序列。
起始幀分界符
:是一個用來表示包起始位置的標記末尾的 FCS(幀校驗序列)
:用來檢查包傳輸過程是否有損壞
最后網卡會將包轉為電信號,通過網線發送出去。
交換機
交換機的設計是將網絡包原樣轉發到目的地。交換機工作在 MAC 層,也稱為二層網絡設備。
交換機的包接收操作
-
電信號到達網線接口,交換機里的模塊進行接收,接下來交換機里的模塊將電信號轉換為數字信號。
-
通過包末尾的 FCS 校驗錯誤,如果沒問題則放到緩沖區。
- 計算機的網卡本身具有 MAC 地址,并通過核對收到的包的接收方 MAC 地址判斷是不是發給自己的,如果不是發給自己的則丟棄;
- 交換機的端口不核對接收方 MAC 地址,而是直接接收所有的包并存放到緩沖區中。
- 和網卡不同,交換機的端口不具有 MAC 地址。
-
查詢這個包的接收方 MAC 地址是否已經在 MAC 地址表中有記錄了。
交換機根據 MAC 地址表查找 MAC 地址,然后將信號發送到相應的端口。
路由器
網絡包經過交換機之后,現在到達了路由器,并在此被轉發到下一個路由器或目標設備。
-
基本原理:當轉發包時,首先路由器端口會接收發給自己的以太網包,然后路由表查詢轉發目標,再由相應的端口作為發送方將以太網包發送出去。
-
包接收操作:路由器的端口都具有 MAC 地址,只接收與自身地址匹配的包,遇到不匹配的包則直接丟棄。
-
完成包接收操作之后,路由器就會去掉包開頭的 MAC 頭部。
-
轉發操作:
-
查詢路由表判斷轉發目標
-
找不到匹配路由時,就會選擇默認路由,路由表中子網掩碼為 0.0.0.0 的記錄表示「默認路由」。
-
-
發送操作:
- 根據路由表的網關列判斷對方的地址。
- 如果網關是一個 IP 地址,則是要轉發到的目標地址,還未抵達終點,還需繼續需要路由器轉發。
- 如果網關為空,則 IP 頭部中的接收方 IP 地址就是要轉發到的目標地址,說明已抵達終點 。
- 通過 ARP 協議根據 IP 地址查詢 MAC 地址,并將查詢的結果作為接收方 MAC 地址。
- 在 ARP 緩存中查詢,如果找不到則發送 ARP 查詢請求。
- 發送方 MAC 地址字段,這里填寫輸出端口的 MAC 地址。還有一個以太類型字段,填寫
0800
(十六進制)表示 IP 協議。 - 網絡包完成后,接下來會將其轉換成電信號并通過端口發送出去。
- 發送出去的網絡包會通過交換機到達下一個路由器,經過層層轉發之后,網絡包就到達了最終的目的地。
- 根據路由表的網關列判斷對方的地址。
在網絡包傳輸的過程中,源 IP 和目標 IP 始終是不會變的,一直變化的是 MAC 地址,因為需要 MAC 地址在以太網內進行兩個設備之間的包傳輸。
路由器與交換機的區別
- 路由器是基于 IP 設計的,俗稱三層網絡設備,路由器的各個端口都具有 MAC 地址和 IP 地址;
- 交換機是基于以太網設計的,俗稱二層網絡設備,交換機的端口不具有 MAC 地址。
服務器與客戶端
- 服務器接收處理請求包:數據包抵達服務器,依次解析:
- MAC 頭(匹配則接收)
- IP 頭(確認協議為 TCP )
- TCP 頭(校驗序列號,匹配則緩存并回 ACK,結合端口號確定給 HTTP 進程 ),HTTP 進程封裝網頁為響應報文
- 響應報文回傳客戶端:響應報文添加 TCP、IP、MAC 頭(源為服務器 IP,目的為客戶端 IP ),經網卡、交換機、路由器跳轉傳輸,到達客戶端所在路由器后,經交換機轉發給客戶端。
- 客戶端處理與斷開連接:客戶端解析數據包獲取 HTTP 響應報文,交由瀏覽器渲染頁面,之后通過 TCP 四次揮手斷開連接 。
網絡模型
OSI 網絡模型(7 層)
開放式系統互聯通信參考模型(Open System Interconnection Reference Model),也就是 OSI 網絡模型,該模型主要有 7 層,分別是應用層、表示層、會話層、傳輸層、網絡層、數據鏈路層以及物理層。
每一層負責的職能都不同,如下:
- 應用層,負責給應用程序提供統一的接口;
- 表示層,負責把數據轉換成兼容另一個系統能識別的格式;
- 會話層,負責建立、管理和終止表示層實體之間的通信會話;
- 傳輸層,負責端到端的數據傳輸;
- 網絡層,負責數據的路由、轉發、分片;
- 數據鏈路層,負責數據的封幀和差錯檢測,以及 MAC 尋址;
- 物理層,負責在物理網絡中傳輸數據幀;
TCP/IP 網絡模型(4層)
Linux 系統正是按照這套網絡模型來實現網絡協議棧的。
TCP/IP 網絡模型共有 4 層,分別是應用層、傳輸層、網絡層和網絡接口層,每一層負責的職能如下:
- 應用層,負責向用戶提供一組應用程序,比如 HTTP、DNS、FTP 等;
- 傳輸層,負責端到端的通信比如 TCP、UDP 等;
- 網絡層,負責網絡包的封裝、分片、路由、轉發,比如 IP、ICMP 等;
- 網絡接口層,負責網絡包在物理網絡中的傳輸,比如網絡包的封幀、 MAC 尋址、差錯檢測,以及通過網卡傳輸網絡幀等;
關系
七層和四層負載均衡,是用 OSI 網絡模型來描述的,
- 七層對應的是應用層,
- 四層對應的是傳輸層。
Linux 網絡協議棧
Linux 網絡協議棧:
Linux 接收網絡包的流程
- 網卡接收與數據寫入:網卡通過 DMA 技術,將接收的網絡包寫入指定內存地址(Ring Buffer 環形緩沖區 )。
網卡:是計算機里的一個硬件,專門負責接收和發送網絡包。
- 網絡包已到達的初始通知方式及問題:
- 最初靠觸發中斷告知操作系統,即網卡收包觸發中斷,讓系統知曉。
- 但在高性能網絡場景,包數量多會頻繁觸發中斷,使 CPU 忙于處理中斷,影響系統整體效率。
- 引入 NAPI 機制優化:Linux 內核 2.6 版本引入 NAPI 機制,以混合 「中斷和輪詢」方式收包。
NAPI 機制核心概念:不采用中斷的方式讀取數據,而是首先采用中斷喚醒數據接收的服務程序,然后 poll 的方法來輪詢數據。
- 硬件中斷處理流程:
- 網卡發硬件中斷給 CPU,CPU 依中斷表調用中斷處理函數。
- 中斷處理函數先 「暫時屏蔽中斷」,讓網卡下次再收到數據包直接寫內存,避免 CPU 持續被中斷;接著發起 「軟中斷」,再恢復屏蔽的中斷,后續主要工作交給軟中斷處理函數 。
網絡協議棧
- 進入網絡接口層:檢查報文合法性,非法則丟棄;合法則識別上層協議類型(IPv4/IPv6 等 ),去掉幀頭幀尾,交給網絡層。
- 到網絡層:取出 IP 包,判斷網絡包走向;若發往本機,識別上層協議(TCP/UDP ),去掉 IP 頭,交給傳輸層。
- 傳輸層:取出 TCP/UDP 頭,依據四元組(源 IP、源端口、目的 IP、目的端口 )找對應 Socket,將數據放入其接收緩沖區。
- 應用層:程序調用 Socket 接口,把內核 Socket 接收緩沖區數據拷貝到應用層緩沖區,喚醒用戶進程 ,至此完成網絡包接收。 還提及可結合圖看接收(左)與發送(右,反向流程 )流程。
Linux 發送網絡包的流程
- 應用層與內核態切換及初始準備:應用程序調用 Socket 發送接口(系統調用),從用戶態陷入內核態 Socket 層;內核申請
sk_buff
內存,將用戶數據拷貝至sk_buff
并加入發送緩沖區 。 - 協議棧逐層處理(以 TCP 為例)
- 網絡協議棧從發送緩沖區取出
sk_buff
,按 TCP/IP 協議棧從上到下處理;若為 TCP 傳輸,因需支持丟包重傳(ACK 確認前sk_buff
不能刪 ),會拷貝新sk_buff
副本用于后續發送,收到 ACK 后釋放原始sk_buff
。 - 填充各層首部:依次填充 TCP 頭、IP 頭(網絡層選取路由、填充 IP 頭、netfilter 過濾、可能分片 )、幀頭和幀尾(網絡接口層通過 ARP 獲下一跳 MAC 地址填充 ),
sk_buff
借助data
指針調整適配各層數據表示(如應用層data
、TCP 層segment
等 )。
- 網絡協議棧從發送緩沖區取出
- 網卡發送及后續處理
- 網絡接口層將
sk_buff
放入網卡發送隊列,觸發“軟中斷”告知驅動;驅動讀取sk_buff
掛到RingBuffer
,映射到網卡可訪問內存 DMA 區域后實際發送 。 - 發送完成后,網卡觸發“硬中斷”釋放內存(
sk_buff
及RingBuffer
內存 );傳輸層收到 TCP 報文 ACK 應答,釋放原始sk_buff
。
- 網絡接口層將
發送網絡數據的內存拷貝操作
- 第一次拷貝:調用發送數據系統調用時,內核申請內核態
sk_buff
,將用戶待發送數據拷貝到sk_buff
并加入發送緩沖區 。 - 第二次拷貝:使用 TCP 傳輸協議時,從傳輸層進入網絡層,為實現可靠傳輸(等待 ACK ),
sk_buff
會被克隆新副本送網絡層,發送完副本釋放,原始保留到收到 ACK 。 - 第三次拷貝:IP 層發現
sk_buff
大于 MTU 時,申請額外sk_buff
,將原sk_buff
拷貝為多個小sk_buff
分片發送 。