TCP詳解

不要必應發表於2019-08-30

1. TCP

1.1 概念

  • 面向連線、可靠的基於位元組流的傳輸協議。
  • 將應用層的的資料分割成報文段併傳送給目標節點的 TCP 層
  • 每個資料包都有相對應的序號,對方收到後就傳送 ACK 確認,未收到就重傳
  • 使用校驗和來檢測傳輸過程中是否出現錯誤

1.2 TCP 報文頭

TCP 報文頭

1.3 TCP 報文頭欄位含義

1. Source Port和Destination Port:

分別佔用16位,表示源埠號和目的埠號,用於區別主機中的不同程式, 而IP地址是用來區分不同的主機的,源埠號和目的埠號配合上IP首部中的源IP地址和目的IP地址就能唯一 的確定一個TCP連線。

2. Sequence Number:

用來標識從TCP發端向TCP收端傳送的資料位元組流,它表示在這個報文段中的的第一個資料 位元組在資料流中的序號;主要用來解決網路報文亂序的問題。

3. Acknowledgment Number:

32位確認序列號包含傳送確認的一端所期望收到的下一個序號,因此,確認序號應 當是上次已成功收到資料位元組序號加1。不過,只有當標誌位中的ACK標誌(下面介紹)為1時該確認序列號的字 段才有效。主要用來解決不丟包的問題。

4. Offset:

給出首部中32 bit字的數目,需要這個值是因為任選欄位的長度是可變的。這個欄位佔4bit(最多能 表示15個32bit的的字,即4*15=60個位元組的首部長度),因此TCP最多有60位元組的首部。然而,沒有任選欄位, 正常的長度是20位元組。

5. TCP Flags:

TCP首部中有6個標誌位元,它們中的多個可同時被設定為1,主要是用於操控TCP的狀態機的,依次 為URG,ACK,PSH,RST,SYN,FIN。每個標誌位的意思如下:

  • URG:此標誌表示TCP包的緊急指標域(後面馬上就要說到)有效,用來保證TCP連線不被中斷,並且督促 中間層裝置要儘快處理這些資料。

  • ACK 此標誌表示應答域有效,就是說前面所說的TCP應答號將會包含在TCP資料包中;有兩個取值:0和1, 為1的時候表示應答域有效,反之為0。

  • PSH:這個標誌位表示Push操作。所謂Push操作就是指在資料包到達接收端以後,立即傳送給應用程式, 而不是在緩衝區中排隊。

  • RST:這個標誌表示連線復位請求。用來複位那些產生錯誤的連線,也被用來拒絕錯誤和非法的資料包。

  • SYN:表示同步序號,用來建立連線。SYN標誌位和ACK標誌位搭配使用,當連線請求的時候,SYN=1, ACK=0;連線被響應的時候,SYN=1,ACK=1;這個標誌的資料包經常被用來進行埠掃描。掃描者傳送 一個只有SYN的資料包,如果對方主機響應了一個資料包回來 ,就表明這臺主機存在這個埠;但是由於這 種掃描方式只是進行TCP三次握手的第一次握手,因此這種掃描的成功表示被掃描的機器不很安全,一臺安全 的主機將會強制要求一個連線嚴格的進行TCP的三次握手。

  • FIN:表示傳送端已經達到資料末尾,也就是說雙方的資料傳送完成,沒有資料可以傳送了,傳送FIN標誌 位的TCP資料包後,連線將被斷開。這個標誌的資料包也經常被用於進行埠掃描。

6. Window:

滑動視窗大小 (流量控制)。

7. 校驗和:

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

8. 緊急指標:

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

9. 選項和填充:

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

10. 資料部分:

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

2. 三次握手

2.1 原因

為什麼需要三次握手:

  • IP 是位於網路層的無連線的通訊協議,IP 協議只負責將 IP 包送往傳送給目的地,但不確保傳送到目的地,所以在傳輸層採用有連線的方式,來確保資料的送 達。

2.2 概念

所謂三次握手是指建立一個 TCP 連線時需要客戶端和伺服器端總共傳送三個包以確認連線的建立。在socket程式設計中,這一過程由客戶端執行connect來觸發。

2.3 三次握手的流程圖

三次握手的流程圖

2.4 流程圖的解釋

  • 第一次握手:客戶端將標誌位SYN置為1,隨機產生一個值seq=J,並將該資料包傳送給伺服器端,客戶端進入SYN_SENT狀態,等待伺服器端確認。
  • 第二次握手:伺服器端收到資料包後由標誌位SYN=1知道客戶端請求建立連線,伺服器端將標誌位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,並將該資料包傳送給客戶端以確認連線請求,伺服器端進入SYN_RCVD狀態。
  • 第三次握手:客戶端收到確認後,檢查ack是否為J+1,ACK是否為1,如果正確則將標誌位ACK置為1,ack=K+1,並將該資料包傳送給伺服器端,伺服器端檢查ack是否為K+1,ACK是否為1,如果正確則連線建立成功,客戶端和伺服器端進入ESTABLISHED狀態,完成三次握手,隨後客戶端與伺服器端之間可以開始傳輸資料了。

2.5 安全隱患

2.5.1 首次握手 —— SYN 超時

在 Server 收到 Client 的 SYN 之後,回覆 SYN-ACK 的時候未收到 ACK 確認,導致服務端不斷重試,直到超時。

2.5.2 SYN Flood 攻擊

惡意程式會在短時間對伺服器不斷髮起建立連線請求,但不響應伺服器請求,導致伺服器不斷重發,佔用資源,導致崩潰。

2.5.3 應對 SYN Flood 攻擊的方式
  • SYN 佇列滿後,通過 tcp_syncookies 引數回發 SYN Cookie
  • 若為正常連線,則 Client 會回發 SYN Cookie,建立連線

2.6 建立連線後,Client 故障

2.6.1 保活機制

向 Client 傳送探測報文,如果未收到響應則繼續傳送,直到收到響應或達到保活探測數時,中斷連線。

3. 四次揮手

3.1 原因

由於TCP連線是全雙工的,因此,每個方向都必須要單獨進行關閉,這一原則是當一方完成資料傳送任務後,傳送一個FIN來終止這一方向的連線,收到一個FIN只是意味著這一方向上沒有資料流動了,即不會再收到資料了,但是在這個TCP連線上仍然能夠傳送資料,直到這一方向也傳送了FIN。

3.2 概念

四次揮手即終止TCP連線,就是指斷開一個TCP連線時,需要客戶端和服務端總共傳送4個包以確認連線的斷開。在socket程式設計中,這一過程由客戶端或服務端任一方執行close來觸發。

3.3 四次揮手流程圖

四次揮手流程圖

3.4 為什麼客戶端傳送完最後一個 ACK 包之後還需要 TIME-WAIT

  • 確保有足夠的時間讓對方接收到 ACK 包
  • 避免新舊連線混淆

3.5 伺服器出現大量 CLOSE-WAIT 狀態的原因

客戶端關閉 socket 連線,服務端忙於處理讀或寫,沒有及時關閉連線

  • 檢查程式碼,特別是資源釋放程式碼
  • 檢查配置,特別是處理請求的執行緒配置

4. TCP 滑動視窗

4.0 必知必會

RTT

傳送資料包到收到對應的 ACK,中間所花費的時間

RTO

重傳時間間隔(經過 RTT 計算得到)

4.1 滑動視窗的作用

TCP 使用滑動視窗做流量控制和亂序重排

相關文章