TCP/IP 五層協議
在講解 TCP/IP 通訊傳輸流之前,首先複習一下 TCP/IP 的五層協議。
應用層:決定向使用者提供應用服務時通訊的活動。TCP/IP 協議族內預存了各類通用的應用服務。比如:FTP、DNS、HTTP 協議。
傳輸層:傳輸層對上層應用層,提供處於網路連線中的兩臺計算機之間的資料傳輸。在傳輸層有兩個性質不同的協議,分別是 TCP (Transmission Control Protocol,傳輸控制協議) 和 UDP (User Data Protocol,使用者資料包協議)
網路層:網路層用來處理在網路上流動的資料包。資料包是網路傳輸的最小資料單位。該層規定了通過怎樣的路徑到達對方計算機,並把資料包傳送給對方。與對方計算機通過多臺計算機或網路裝置進行傳輸時,網路層所起的作用就是在眾多的選項內選擇一條傳輸路線。
資料鏈路層: 在物理層提供位元流服務的基礎上,建立相鄰結點之間的資料鏈路,通過差錯控制提供資料幀 (Frame)在通道上無差錯的傳輸,並進行各電路上的動作系列。資料的單位稱為幀 (frame)
物理層:物理層建立在物理通訊介質的基礎上,作為系統和通訊介質的介面,用來實現資料鏈路實體間透明的位元 (bit) 流傳輸。只有該層為真實物理通訊,其它各層為虛擬通訊。
TCP/IP 資料傳輸流程
客戶端在應用層 (HTTP 協議) 發出一個 HTTP 請求。
為了方便傳輸,在傳輸層 (TCP 協議) 把從應用層處收到的資料 (HTTP 請求報文) 進行分割,並在各個報文上打上標記序號及埠號後轉發給網路層。
在網路層 (IP 協議),增加作為通訊目的地的 MAC 地址後轉發給資料鏈路層。這樣,傳送給服務端的請求就準備齊全了。
當服務端在鏈路層接收到資料時,按序往上層傳送,一直到應用層。當傳輸到應用層時,才算真正的接收到由客戶端傳送過來的請求。
什麼是 MAC 地址?
媒體訪問控制地址 (Media Access Control Address),也稱為區域網地址 (LAN Address),乙太網地址 (Ethernet Address) 或實體地址 (Physical Address),它是一個用來確認網上裝置位置的地址。ARP (Address Resolution Protocol) 是一種用來解析地址的協議,它可以根據 IP 地址反查出對應的 MAC 地址。
下圖展示了一臺電腦內網 IP 和 MAC 地址。在終端 (MAC OS 環境) 輸入 ifconfig,找到 en0,便可查詢本地乙太網的資訊。
那麼什麼是 MAC 地址呢?我們知道 IP 地址是可變的,可以通過各種方式分配 IP 地址給一個裝置,比如 DHCP, PPP,靜態 IP 等。而 MAC 地址一般來講是不會變的,裝置在生產時就被“烙”上了 唯一的標識,這個 唯一的標識 就是 MAC 地址。
逼乎上有個很有趣的例子:你中午在公司點了份外賣,收貨地址一定是寫公司的地址;晚上回到家,再點外賣時就得把地址寫成家 (IP 是動態的)。但無論在哪兒點外賣,訂單上的姓名和手機號一定是你自己的 (MAC 地址)。
中午外賣小哥把午餐送到公司門口,但收外賣的人肯定不止你一個 (多臺裝置在同一個 broadcast 網路裡),因此他會通過手機號和姓名來找到你。
UDP 協議
使用者資料包協議 (User Datagram Protocol),又稱使用者資料包協議,是一個簡單的面向資料包的傳輸協議。在 TCP/IP 模型中,UDP 為網路層以上和應用層以下提供了一個簡單的介面。UDP 只提供資料的 不可靠傳遞,它一旦把應用程式發給網路層的資料傳送出去,就不保留資料備份。UDP 在 IP 資料包的頭部僅僅加入了複用和資料校驗 (欄位)。
它的特點如下
-
UDP 缺乏可靠性。UDP 本身不提供確認序號,序列號,超時重傳等機制。UDP 資料包可能在網路中被複制,被重新排序。即 UDP 不保證資料包會到達其最終目的地,也不保證各個資料包的先後順序,也不保證每個資料包只到達一次。
-
UDP 頭部開銷小,它包含以下幾個資料:
兩個十六位的埠號,分別是源埠和目的埠。 整個資料包文的長度。 整個資料包文的校驗和,用於發現頭部資訊和資料中的錯誤 複製程式碼
-
UDP 是面向無連線的。UDP 客戶端和伺服器之前不必存在長期的關係。UDP 傳送資料包之前也不需要經過握手建立連線的過程。
-
UDP 不僅支援單播,還支援多播和廣播。
域名系統 (DNS)
DNS在進行區域傳輸的時候使用TCP協議,其它時候則使用UDP協議;
複製程式碼
簡單網路管理協議 (SNMP)
動態主機配置協議 (DHCP)
路由資訊協議 (RIP)
TCP 協議
TCP (Transmission Control Protocol, 傳輸控制協議) 是一種面向連線的、可靠的、基於位元組流服務的傳輸層通訊協議,由 IETF 的 RFC 793 定義。其中位元組流服務 (Byte Stream Service) 是指為了方便傳輸,將大塊資料分割成以報文段 (segment) 為單位的資料包進行管理。
-
TCP 提供一種面向連線的、可靠的位元組流服務
-
在一個 TCP 連線中,僅有兩方進行彼此通訊。廣播和多播不能用於 TCP
-
TCP 使用校驗和,確認和重傳機制來保證可靠傳輸
-
TCP 給資料分節進行排序,並使用累積確認保證資料的順序不變和非重複
-
TCP 使用滑動視窗機制來實現流量控制,通過動態改變視窗的大小進行擁塞控制
TCP 報文
埠號:包括源埠號和目的埠號,用來標識同一臺計算機的不同的應用程式。TCP 報頭中的源埠號和目的埠號同 IP 資料包中的源 IP 與目的 IP 唯一確定一條 TCP 連線。源埠號:源埠和 IP 地址的作用是標識報文的返回地址。
目的埠號:目的埠指明接收方計算機上的應用程式介面。
序號:它是當前報文段傳送的資料組的第一個位元組的序號。在 TCP 傳送的流中,每一個位元組一個序號。比如一個報文段的序號為 300,此報文段的資料部分共有 100 位元組,則下一個報文段的序號為 400。序號 確保了 TCP 傳輸的有序性。
**確認號:**即 ACK(acknowledgement),指明下一個期待收到的位元組序號,表明該序號之前的所有資料已經正確無誤的收到。確認號只有當 ACK 標誌為 1 時才有效。比如建立連線時,SYN 報文的 ACK 標誌位為 0。
首部長度:由於首部可能含有可選項內容,因此 TCP 報頭的長度是不確定的,報頭不包含任何任選欄位則長度為 20 位元組,4 位首部長度欄位所能表示的最大值為 1111,轉化為 10 進製為 15,15*32/8 = 60,故報頭最大長度為 60 位元組。首部長度也叫資料偏移,是因為首部長度實際上指示了資料區在報文段中的起始偏移值。
保留:為將來定義新的用途保留,現在一般置 0。
視窗:滑動視窗大小,用來告知傳送端接受端的快取大小,以此控制傳送端傳送資料的速率,從而達到流量控制。視窗大小是一個 16bit 欄位,因此視窗大小最大為 65535。
校驗和:奇偶校驗,此校驗和是對整個的 TCP 報文段,包括 TCP 頭部和 TCP 資料,以 16 位字進行計算所得。由傳送端計算和儲存,並由接收端進行驗證。
緊急指標:只有當 URG 標誌置 1 時緊急指標才有效。緊急指標是一個正的偏移量,和順序號欄位中的值相加表示緊急資料最後一個位元組的序號。 TCP 的緊急方式是傳送端向另一端傳送緊急資料的一種方式。
選項和填充:最常見的可選欄位是最長報文大小,又稱為 MSS (Maximum Segment Size),每個連線方通常都在通訊的第一個報文段 (為建立連線而設定 SYN 標誌為 1 的那個段)中指明這個選項,它表示本端所能接受的最大報文段的長度。選項長度不一定是 32 位的整數倍,所以要加填充位,即在這個欄位中加入額外的零,以保證 TCP 頭是 32 的整數倍。
資料部分:TCP 報文段中的資料部分是可選的。在一個連線建立和一個連線終止時,雙方交換的報文段僅有 TCP 首部。如果一方沒有資料要傳送,也使用沒有任何資料的首部來確認收到的資料。在處理超時的許多情況中,也會傳送不帶任何資料的報文段。
上面寫了那麼多是不是不太好記,其實不用全都記住,記住個大概流程
複製程式碼
TCP 建立連線 (三次握手)
所謂三次握手 (three-way handshaking) 是指建立一個 TCP 連線時,需要客戶端和服務端共傳送三個包。它的目的是連線伺服器指定埠,建立 TCP 連線,並同步雙方的 序列號 和 確認號,交換 TCP 視窗大小資訊。在 socket 程式設計中,當客戶端執行 connect() 函式時,將觸發三次握手。
SYN:同步序列編號(Synchronize Sequence Numbers)。是TCP/IP建立連線時使用的握手訊號。在客戶機和伺服器之間建立正常的TCP網路連線時,客戶機首先發出一個SYN訊息,伺服器使用SYN+ACK應答表示接收到了這個訊息,最後客戶機再以ACK訊息響應。這樣在客戶機和伺服器之間才能建立起可靠的TCP連線,資料才可以在客戶機和伺服器之間傳遞。
seq:序列號,什麼意思呢?當傳送一個資料時,資料是被拆成多個資料包來傳送,序列號就是對每個資料包進行編號,這樣接受方才能對資料包進行再次拼接。
ack:這個代表下一個資料包的編號,這也就是為什麼第二請求時,ack是seq+1,
第一次握手
客戶端首先傳送一個 SYN 為 1 的包給服務端,指明客戶端要連線服務端的哪個介面以及初始序號 x。傳送完畢後,客戶端進入 SYN_SEND 狀態。
第二次握手
服務端收到後,回傳一個帶有 SYN/ACK 的確認包以示應答。即 SYN=1,ACK=1。服務端選擇自己的 ISN 序列號,放到 seq 中,同時將確認序號 ack 設定為客戶端的 ISN+1,即 x+1。傳送完畢後,服務端進入 SYN_RCVD (同步收到) 狀態。
第三次握手
客戶端收到確認後,再次傳送一個帶 ACK 標誌的資料包。即 ACK=1,ack=y+1,並將自己的序列號 seq=x+1。傳送完畢後,客戶端和伺服器雙雙進入 ESTABLISHED 狀態。至此,三次握手結束。
TCP 關閉連線 (四次揮手)
第一次揮手
客戶端呼叫 close() 函式,併傳送一個 FIN (finish) 標誌為 1 的資料包給服務端,來表示本方的資料已經全部傳送完畢,此時客戶端進入 FIN_WAIT_1 狀態。TCP 規定,FIN 報文段即使不攜帶資料,也要消耗一個序號。
第二次揮手
服務端收到客戶端的釋放報文後,發出確認報文,其中 ACK=1, ack=u+1,並且帶上自己的序列號 seq=v。表明自己接受到了客戶端關閉連線的請求,但還沒準備好關閉連線 (半關閉狀態),也就是說客戶端已經沒有資料要傳送了,但服務端仍有可能會傳送資料。傳送完畢後,服務端進入 CLOSE_WAIT 狀態。
當客戶端收到該報文後,客戶端就進入 FIN-WAIT-2 狀態,等待伺服器傳送連線釋放報文。
第三次揮手
伺服器端準備好關閉連線時,會向客戶端傳送一個連線釋放報文,其中 FIN=1,ack=u+1。由於在半關閉狀態,伺服器很可能又傳送了一些資料,假定此時的序列號為 seq=w。傳送完畢後,服務端便進入 LAST-ACK(最後確認) 狀態。
第四次揮手
客戶端收到伺服器的連線釋放報文後,需要傳送一個確認包,其中 ACK=1,ack=w+1,而自己的序列號是 seq=u+1,並進入了 TIME-WAIT (時間等待)狀態,等待過程可能出現的要求重傳的 ACK 包。
此時 TCP 連線還沒有釋放,必須經過 2 * MSL (Maximum Segment Lifetime, 最長報文段壽命) 時間後,當客戶端撤銷相應的 TCB 後,才會進入 CLOSED 狀態。
而伺服器只要收到了客戶端發出的確認,立即進入 CLOSED 狀態。同樣,撤銷 TCB 後,就結束了這次的 TCP 連線。因此,伺服器結束 TCP 連線的時間要比客戶端早一些。