1. TCP/IP的一些關鍵特性
- 面向連接
先建立連接,再進行數據傳輸。 - 雙向字節流
使用字節流來實現雙向數據通信 - 有序傳輸
數據的接收順序和它們的發送順序一致- 基於ACK的可靠傳輸
沒有收到ACK的時候,發送方會重傳 - 流控
- 擁塞控制
2. 數據發送
參看如下這張圖,
這張圖裏面的這些處理層可以分成三層
- 用戶空間
- 內核空間
- 設備空間
用戶空間和內核空間的任務都通過CPU來執行。用戶空間和內核空間通常稱爲host,區別於設備空間。
2.1. 用戶空間管理
首先我們來看看用戶空間。首先要用程序創建數據併發送,進行系統調用write()發送數據,這個時候就切換到了內核空間。 內核空間有兩個緩存 - 第一個是用於發送的send socket buffer; - 另一個是用於接收的receive socket buffer;
2.2. 內核空間處理
Sockets處理
應用程序調用了write後,要發送的數據包就從用戶空間拷貝到內核空間的send socket buffer的尾部。
2.3. TCP層處理
接下來調用TCP,每個socket都有一個相關聯的TCP控制塊(TCB)。依據這個控制塊來控制TCP連接上的傳輸,如果允許數據傳輸,會把一個新的TCP段接到數據包的前面, 如下圖所示的包含兩段:TCP Header和Payload數據
TCP幀結構
2.4. IP層處理
這個時候從TCP層來到IP層,IP層會添加一個IP頭到TCP數據段上,這個時候IP routing就開始搜索下一跳的IP(爲了數據包能到達最終目的IP); 比如說IP路由發現是一個外網地址,需要先發送到網關,那麼網關IP就是下一跳的IP。 如下圖所示的就是IP頭的結構,裏面包含了源IP和目的IP,IP路由會依據這個消息來尋找下一跳的地址。
NOTE: Wiki上面對於IP Routing的解釋: IP routing 指的是在IP網絡中轉發IP數據包的路由機制,IP路由包含了決定網絡包傳輸的最合適路徑;包含了靜態配置路由和動態獲取狀態信息來進行選擇指定的兩種機制,主要是找到下一跳的IP地址,這樣數據包可以儘快的到達它的最終目的地。 網絡通常會被網關或者路由隔離開。路由器上任何接口收到的數據包,都會先檢查它的目的地址和源地址,然後依據目的地址和路由規則把數據包放到相應輸出接口的隊列中;路由表中會包含所有接口和它們所連接網絡的路由規則,如果沒有路由規則滿足收到的網絡表,那麼會依據默認路由規則來發送;路由表可以是靜態的,由管理者進行配置,也可以是動態更新的; 路由算法 IP轉發算法是一個特殊的路由實現;這個算法利用路由表來選擇下一跳的的路由,被選中的IP就是作爲下一跳的路由;如果有多個規則匹配,那麼選擇子網掩碼最長的那個; 假定目的地址是, D, 網路前綴是, N: if ( N 匹配直連的IP地址 ) 數據塊發送到D到這個網絡連接; else if ( 路由表包含一個到N的路由 ) 數據塊發送到路由表中列着的下一跳的地址; else if ( 存在一個默認路由 ) 發送到默認路由; else 返回轉發錯誤;
有一種場景,如果說數據包的對端IP和當前IP屬於同一網段
NOTE: Linux系統中每個配置了IP的eth設備都有一條默認的路由表信息,比如說當前主機有個網卡,配置了IP是192.168.56.101/24;那麼就會有一條默認的路由信息192.168.56.0/24 dev enp0s8 proto kernel scope link src 192.168.56.101 metric 100;也就是說所有發往這個網段的消息都會經過網口enp0s8發送出去,比如說要發往192.168.56.100,那麼接下來在數據鏈路層的時候就會通過ARP來獲取這個IP對應的MAC地址;加入說.100這個主機和.101這個主機都是連在同一個交換機上,那麼交換機收到這個數據報文後就會觸發二層的轉發(因爲目的的MAC地址不是就是主機100的MAC地址)?
2.5. 網絡層(Ethernet)
網絡層處理的時候,以及知道下一跳的IP了,這個時候需要搜索這個下一跳的IP對應的MAC地址;這個時候就需要ARP消息了,獲取了下一跳的MAC地址以後,就可以添加Ethernet header了
這個裏面就包含了源MAC地址和目的MAC地址了。 IP路由做完了以後,其實以及知道這個數據包要通過哪個NIC進行傳輸了,這個時候就該調用這個NIC來把數據包發送到下一跳的地址了。
3. 數據接收
接下來我們看看數據接收的過程是怎麼進行的
NIC收到數據包之後,進行校驗,然後發送到內核空間處理
3.1. Ethernet層處理
首先檢查這個包是否合法,同時檢查目的MAC地址是否匹配當前的的網口;然後數據發到IP層處理;
3..2. IP層處理
IP層也會檢查這個包的合法性,然後邏輯上檢查這個包是要執行IP路由還是要在當前系統下處理這個包,或者要轉發到其他系統;如果要在本機處理,那麼會解碼上層協議棧(傳輸層),比如說TCP的proto值是6,如果解出來是6,那麼發送到TCP層進行處理
3.3. TCP層處理
首先還是合法性檢查,然後查找TCP控制塊;如果是新傳數據,那麼把新數據包添加到receive sock buffer的尾部。
文末給大家分享一個實現網絡協議棧的視頻:
tcpip協議棧與網絡API的關聯 ||Posix網絡API與TCP的關聯 ||TCP三次握手||沒有epoll的前提下,爲什麼UDP的併發性比TCP強