🐳第一部分:什么是TCP和UDP?
先給結論:TCP 和 UDP 都是傳輸層協議,負責把數據從一臺電腦 “搬” 到另一臺電腦,但它們的 “搬運風格” 完全不同
📦 比喻:TCP 像 "打電話",UDP 像 "寫信"
- TCP(Transmission Control Protocol,傳輸控制協議):
就像打電話—— 必須先 “撥通對方號碼”(三次握手建立連接),通話中能"實時確認對方聽到"(通過確認應答、重傳機制保障可靠),掛電話前還要"說清楚再見"(四次揮手斷開連接)。
核心是雙向確認、實時反饋,確保對話完整、有序。 - UDP(User Datagram Protocol,用戶數據報協議):
就像寫信—— 寫好內容、填完地址,直接丟進郵筒(無需確認對方是否在線)。信寄出去后,不管對方收沒收到、內容是否完整(丟包、亂序不管),自己的 "發送任務 "就結束了。
核心是簡單快捷、無需等待,追求 “發出去就行”
📌 一句話總結:
TCP 像"實時電話",追求穩、準、全;UDP 像 "投信",追求快、簡、省。
🐳第二部分:TCP的三次握手和四次揮手
2.1 TCP的三次握手🌈
🤝1.第一次握手(客戶端→服務器)
- SYN 標志位:此時 SYN 標志位被置為 1,表示客戶端希望與服務器建立一個 TCP 連接。
- 序列號(Sequence Number,seq):客戶端會隨機生成一個初始序列號,比如記為 x 。這個序列號用于標識客戶端在這個連接中發送的第一個字節的數據,后續發送的數據會基于這個序列號進行編號。 比如后續發送的數據長度為 100 字節,那下一個數據段的起始序列號就是 x + 100。
在第一次握手時,客戶端向服務器發送一個帶有 SYN 標志位且包含初始序列號 x 的 TCP 報文段,此時該報文段不包含 ACK 標志位,因為還沒有收到服務器的確認信息。
🤝2.第二次握手(服務器→客戶端)
- SYN 標志位:同樣被置為 1 ,這是因為服務器在收到客戶端的連接請求后,也同意建立連接,所以使用 SYN 標志位來同步自己的初始序列號。
- 序列號(seq):服務器也會隨機生成一個初始序列號,比如記為 y 。
- ACK 標志位:被置為 1,表示服務器對客戶端發送的 SYN 報文進行確認。
- 確認號(Acknowledgment Number,ack):其值為客戶端初始序列號 x 加 1,即 ack = x + 1 。這表明服務器已經成功收到了客戶端的 SYN 報文,并且期望客戶端下一次發送的數據從序列號 x + 1 開始。
所以,第二次握手時服務器發送的報文段同時包含了 SYN 和 ACK 標志位,以及服務器自己的初始序列號 y 和對客戶端的確認號 x + 1。
🤝3.第三次握手(客戶端→服務器)
- ACK 標志位:被置為 1,表示客戶端對服務器發送的 SYN + ACK 報文進行確認。
- 確認號(ack):其值為服務器初始序列號 y 加 1,即 ack = y + 1 。這意味著客戶端已經成功收到了服務器的 SYN + ACK 報文,并且期望服務器下一次發送的數據從序列號 y + 1 開始。
- 序列號(seq):其值為客戶端在第一次握手時發送的初始序列號 x 加 1,即 seq = x + 1 ,這是因為在第一次握手時客戶端發送的 SYN 報文也占用了一個序列號
第三次握手時,客戶端發送的報文段主要是一個僅包含 ACK 標志位的確認報文,以及對服務器的確認號 y + 1 和自己的序列號 x + 1。
總結
通過這三次握手,客戶端和服務器雙方都確認了彼此的收發能力正常, 并且就各自的初始序列號達成了一致,從而建立起一個可靠的 TCP 連接,為后續的數據傳輸做好了準備。
2.2 TCP的四次揮手🌈
??一、【核心邏輯】四次揮手的 “靈魂”
為什么需要四次揮手?因為 TCP 是全雙工通信(雙方可以同時發數據),所以斷開連接時:
- 客戶端 → 服務器:"我要關了(FIN)"
- 服務器 → 客戶端:"收到,等我發完剩余數據(ACK)"
- 服務器 → 客戶端:"我也關了(FIN)"
- 客戶端 → 服務器:"收到,確認關閉(ACK)"
??二、【逐次拆解】四次揮手的報文細節
🤝1. 第一次揮手(客戶端 → 服務器):“我沒數據要發了,準備關”
- 行為:客戶端主動發起斷開,發送
FIN
報文。 - 關鍵字段:
-
- FIN 標志位:置為
1
→ 告訴服務器 “我沒數據要發了,準備關閉連接”。 - 序列號(seq):填
u
→ 表示 “這是我最后發的字節流的序列號”(u
是客戶端當前已發數據的最后一個序列號 + 1)。 - 確認號(ack):填
v
→ 表示 “我確認收到你之前發的序列號到v - 1
的數據”(v
是服務器最后一次 ACK 的確認號)。
- FIN 標志位:置為
- 類比:你打電話說 “我這邊說完了,準備掛了”,并告訴對方 “我最后說的內容是第
u
字節”。
🤝2. 第二次揮手(服務器 → 客戶端):“收到關閉請求,等我處理完剩余數據”
- 行為:服務器收到
FIN
后,先回復ACK
確認 “收到關閉請求”,但不立即關閉(可能還有數據沒發完)。 - 關鍵字段:
-
- ACK 標志位:置為
1
→ 告訴客戶端 “我收到你的關閉請求了”。 - 序列號(seq):填
v
→ 表示 “這是我當前要發的字節流的序列號”(v
是服務器已發數據的最后一個序列號 + 1)。 - 確認號(ack):填
u + 1
→ 表示 “我確認收到你seq = u
的FIN
報文,期望你后續(如果有)從u + 1
開始發”(但客戶端已經沒數據發了)。
- ACK 標志位:置為
- 類比:對方說 “好的,我知道你要掛了,等我把最后幾句話說完”,并確認 “你最后說的是第
u
字節,我記住了”。
🤝3. 第三次揮手(服務器 → 客戶端):“我也沒數據發了,你可以關了”
- 行為:服務器處理完所有剩余數據后,主動發送
FIN
報文,告訴客戶端 “我也沒數據了,現在可以關連接了”。 - 關鍵字段:
-
- FIN 標志位:置為
1
→ 告訴客戶端 “我也沒數據要發了,準備關閉”。 - 序列號(seq):填
w
→ 表示 “這是我最后發的字節流的序列號”(w
是服務器處理完剩余數據后的最后一個序列號 + 1)。 - 確認號(ack):填
u + 1
→ 同第二次揮手,繼續確認客戶端的FIN
報文。
- FIN 標志位:置為
- 類比:對方說 “我說完了,你可以掛了”,并告訴客戶端 “我最后說的內容是第
w
字節”。
🤝4. 第四次揮手(客戶端 → 服務器):“收到關閉請求,確認關閉”
- 行為:客戶端收到服務器的
FIN
后,回復ACK
確認 “收到關閉請求”,并等待 2MSL 時間(確保服務器收到 ACK,避免服務器重發FIN
)后關閉連接。 - 關鍵字段:
-
- ACK 標志位:置為
1
→ 告訴服務器 “我收到你的關閉請求了”。 - 序列號(seq):填
u + 1
→ 表示 “這是我回應你的 ACK 報文的序列號”(客戶端已無數據發,序列號延續之前的邏輯)。 - 確認號(ack):填
w + 1
→ 表示 “我確認收到你seq = w
的FIN
報文,期望你后續(如果有)從w + 1
開始發”(但服務器也沒數據發了)。
- ACK 標志位:置為
- 類比:你說 “好的,我知道你說完了,現在徹底掛了”,并確認 “你最后說的是第
w
字節,我收到了”。
完美撒花~
Linux的常見命令:Linux常見的命令(超實用!!!!)-CSDN博客
Linux中jar包腳本:在Linux環境安裝JDK17(保姆級教程)_linux安裝jdk17-CSDN博客
在Docker里面裝PostgreSQL:在Docker里面裝PostgreSQL(保姆級別)_docker安裝postgresql,設置時區,日志掛載出來,配置文件掛載出來-CSDN博客
在Docker中下載Redis和配置:在Docker中下載Redis和配置(保姆級別)_docker 下載redis-CSDN博客
在Docker中下載MySql和配置:在Docker中下載MySql和配置(超詳細!!!)_mysql docker鏡像下載-CSDN博客
在Linux系統中安裝Docker:在Linux系統中安裝Docker(保姆級別)_linux安裝docker csdn-CSDN博客
阿里云服務器的購買以及遠程連接:阿里云服務器入門教程:購買,配置,遠程連接(保姆級別)-CSDN博客
在Linux環境安裝JDK17:在Linux環境安裝JDK17(保姆級教程)_linux安裝jdk17-CSDN博客
在Linux環境安裝Redis:在Linux環境安裝Redis(保姆級教程)_linux 安裝最新版redis-CSDN博客
java中的stream流:Java中的Stream流(保姆級別!!)_流(streams)java,可以定時嘛-CSDN博客
保姆級別idea關聯數據庫的方式:保姆級別IDEA關聯數據庫方式、在IDEA中進行數據庫的可視化操作(包含圖解過程)-CSDN博客
Linux的訪問權限:Linux的訪問權限(保姆級別)-CSDN博客
如何優雅刪除Docker鏡像和容器:如何優雅刪除Docker鏡像和容器(保姆級別)-CSDN博客
最實用的vim指令:最實用的Vi/Vim指令匯總(上手超快!!!)_實用vim-CSDN博客
Git、Gitee、GitHub、GitLab完整講解:從基礎到進階:
Git、Gitee、GitHub、GitLab完整講解:從基礎到進階-CSDN博客