TCP/IP 通訊傳輸流

南果梨發表於2019-05-08

TCP/IP 五層協議

在講解 TCP/IP 通訊傳輸流之前,首先複習一下 TCP/IP 的五層協議。

應用層:決定向使用者提供應用服務時通訊的活動。TCP/IP 協議族內預存了各類通用的應用服務。比如:FTP、DNS、HTTP 協議。

傳輸層:傳輸層對上層應用層,提供處於網路連線中的兩臺計算機之間的資料傳輸。在傳輸層有兩個性質不同的協議,分別是 TCP (Transmission Control Protocol,傳輸控制協議) 和 UDP (User Data Protocol,使用者資料包協議)

網路層:網路層用來處理在網路上流動的資料包。資料包是網路傳輸的最小資料單位。該層規定了通過怎樣的路徑到達對方計算機,並把資料包傳送給對方。與對方計算機通過多臺計算機或網路裝置進行傳輸時,網路層所起的作用就是在眾多的選項內選擇一條傳輸路線。

資料鏈路層: 在物理層提供位元流服務的基礎上,建立相鄰結點之間的資料鏈路,通過差錯控制提供資料幀 (Frame)在通道上無差錯的傳輸,並進行各電路上的動作系列。資料的單位稱為幀 (frame)

物理層:物理層建立在物理通訊介質的基礎上,作為系統和通訊介質的介面,用來實現資料鏈路實體間透明的位元 (bit) 流傳輸。只有該層為真實物理通訊,其它各層為虛擬通訊。

TCP/IP 資料傳輸流程

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,便可查詢本地乙太網的資訊。

TCP/IP 通訊傳輸流

那麼什麼是 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 不僅支援單播,還支援多播和廣播。

TCP/IP 通訊傳輸流
基於 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 通訊傳輸流
埠號:包括源埠號和目的埠號,用來標識同一臺計算機的不同的應用程式。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。

TCP/IP 通訊傳輸流

視窗:滑動視窗大小,用來告知傳送端接受端的快取大小,以此控制傳送端傳送資料的速率,從而達到流量控制。視窗大小是一個 16bit 欄位,因此視窗大小最大為 65535。

校驗和:奇偶校驗,此校驗和是對整個的 TCP 報文段,包括 TCP 頭部和 TCP 資料,以 16 位字進行計算所得。由傳送端計算和儲存,並由接收端進行驗證。

緊急指標:只有當 URG 標誌置 1 時緊急指標才有效。緊急指標是一個正的偏移量,和順序號欄位中的值相加表示緊急資料最後一個位元組的序號。 TCP 的緊急方式是傳送端向另一端傳送緊急資料的一種方式。

選項和填充:最常見的可選欄位是最長報文大小,又稱為 MSS (Maximum Segment Size),每個連線方通常都在通訊的第一個報文段 (為建立連線而設定 SYN 標誌為 1 的那個段)中指明這個選項,它表示本端所能接受的最大報文段的長度。選項長度不一定是 32 位的整數倍,所以要加填充位,即在這個欄位中加入額外的零,以保證 TCP 頭是 32 的整數倍。

資料部分:TCP 報文段中的資料部分是可選的。在一個連線建立和一個連線終止時,雙方交換的報文段僅有 TCP 首部。如果一方沒有資料要傳送,也使用沒有任何資料的首部來確認收到的資料。在處理超時的許多情況中,也會傳送不帶任何資料的報文段。

上面寫了那麼多是不是不太好記,其實不用全都記住,記住個大概流程
複製程式碼

TCP 建立連線 (三次握手)

TCP/IP 通訊傳輸流

所謂三次握手 (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/IP 通訊傳輸流

為什麼是三次握手,兩次不行嗎?

為了實現可靠資料傳輸,TCP 協議的通訊雙方,都必須維護一個序列號,以標識傳送出去的資料包中,哪些是已經被對方收到的。三次握手的過程即是通訊雙方相互告知序列號起始值,並確認對方已經收到了序列號起始值的必經步驟

如果只是兩次握手,至多隻有連線發起方的起始序列號能被確認,另一方選擇的序列號則得不到確認。

如果已經建立了連線,但是客戶端突然出現故障了怎麼辦?

TCP 還設有一個保活計時器 (keep-alive),如果客戶端出現故障,伺服器不能一直等下去,白白浪費資源。伺服器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設定為 2 小時,若兩小時還沒有收到客戶端的任何資料,伺服器就會傳送一個探測報文段,以後每隔 75 秒傳送一次。若一連傳送 10 個探測報文仍然沒反應,伺服器就認為客戶端出了故障,接著就關閉連線。

TCP 關閉連線 (四次揮手)

TCP/IP 通訊傳輸流

第一次揮手

客戶端呼叫 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 連線的時間要比客戶端早一些。

TCP/IP 通訊傳輸流

TCP 有哪些手段保證可靠交付

TCP/IP 通訊傳輸流

udp和tcp的區別

TCP/IP 通訊傳輸流

dns

DNS 報文格式

請求報文和 DNS 伺服器返回的應答報文都是統一的格式:

TCP/IP 通訊傳輸流

會話標識 (2 位元組):它是 DNS 報文的 ID 標識,對於請求報文和其對應的應答報文,這個欄位是相同的,通過它可以區分 DNS 應答報文是哪個請求的響應。

標誌 (2 位元組):它有 8 個部分,如下圖所示:

TCP/IP 通訊傳輸流

TCP/IP 通訊傳輸流

Questions 查詢欄位

QNAME 無符號 8bit 為單位長度不限表示查詢名。

QTYPE 無符號 16bit 整數表示查詢的協議型別。

QCLASS 無符號 16bit 整數表示查詢的類。

Answer/Authority/Additional

三者的格式相同,如下所示:

TCP/IP 通訊傳輸流

DNS 解析記錄

折騰過搭建網站的小夥伴們一定對 DNS 解析記錄不會陌生,下面通過表格複習一下。

TCP/IP 通訊傳輸流

域名解析過程

  • 系統會檢查瀏覽器快取中有沒有這個域名對應的解析過的 IP 地址,如果快取中有,這個解析過程就將結束。瀏覽器快取是受這個域名的失效時間和快取的空間大小控制的。

  • 如果使用者的瀏覽器快取中沒有,瀏覽器會查詢作業系統快取中即為本地的 Host 檔案。

  • 路由器也可能會有快取。

  • 如果前幾步都沒有找到,就會到 LDNS (Local DNS) 中查詢,LDNS 是你的 ISP 分配給你的 DNS (一般為兩個),大部分情況下域名都會在這裡得到解析。下圖是 cloudflare 提供給我的兩個 DNS。

TCP/IP 通訊傳輸流

  • 如果在 LDNS 沒有找到,那就要去 Root Server 域名伺服器請求解析了。根域名伺服器返回給本地域名伺服器一個 查詢主域名伺服器(gTLD Server)地址。gTLD 是國際頂級域名伺服器,如.com,.cn、.org 等,全球只有 13 臺左右。
  • 本地域名伺服器會向 gTLD Server 地址傳送請求,它會返回一個 Name Server 域名伺服器的地址,這個 Name Server 通常就是你註冊域名的廠家,比如 NameCheap、狗爹、萬網等等。
  • Name Server 域名伺服器會查詢儲存域名和 IP 的關係對映表,正常情況下都可以根據域名得到目標 IP 記錄,並連同一個 TTL 返回給本地域名伺服器。
  • 本地域名伺服器根據 TTL 快取這個 IP,並將解析結果返回給客戶端,客戶端再根據 TTL 將 IP 資訊快取到本地系統快取裡。至此,域名解析過程結束。

TCP/IP 通訊傳輸流

相關文章