文章目錄
- TCP/UDP全面詳解
- 什么是TCP和UDP?
- TCP如何保證可靠性?
- 1. 序列號(Sequence Number)
- 2. 確認應答(ACK)
- 3. 超時重傳(Timeout Retransmission)
- 4. 窗口控制(Sliding Window)
- 5. 快速重傳(Fast Retransmit)
- 三次握手(建立連接)
- 四次揮手(斷開連接)
- 為什么是三次握手?為什么是四次揮手?
- 三次握手的原因
- 四次揮手的原因
- TCP和UDP特點
- TCP擁塞控制
- 一、慢啟動(Slow Start)
- 舉例:
- 二、擁塞避免(Congestion Avoidance)
- 舉例:
- 三、超時重傳與慢啟動重啟
- 處理方法:
- 四、快速重傳與快速恢復(Fast Retransmit & Fast Recovery)
- 快速重傳行為:
- 快速恢復行為:
- 擁塞控制減慢增長速度的條件總結
- 擁塞控制會減慢增長速度的時機:
- TCP/IP 數據鏈路層的交互過程簡述
- TCP 和 UDP 如何區分?
- UDP 中的 `connect()` 函數原理
- `connect()` 的作用:
- TCP連接中的 TIME_WAIT 狀態詳解
- 一、TIME_WAIT 狀態如何產生?
- 二、TIME_WAIT 的兩個核心作用
- 1. 確保連接的可靠關閉
- 2. 避免舊連接干擾新連接
- 三、TIME_WAIT 的副作用與優化
- ? 解決方法:
- TCP的模型
TCP/UDP全面詳解
什么是TCP和UDP?
TCP(Transmission Control Protocol)叫傳輸控制協議,是面向連接、可靠傳輸的協議。
UDP(User Datagram Protocol)叫用戶數據報協議,是無連接、盡最大努力交付的協議。
一句話總結:
- TCP可靠但慢,像寄快遞(要簽收、確認收貨)
- UDP快速但可能丟失,像發傳單(發了就發了,收不收無所謂)
TCP如何保證可靠性?
TCP為了確保數據能安全、完整送到對方,設計了很多機制,主要有:
1. 序列號(Sequence Number)
每發送一段數據,TCP都會打個"編號"。
比如發送第一包數據編號1001,第二包編號2001,接收方按照編號順序排列,避免了丟包、亂序問題。
2. 確認應答(ACK)
接收方收到數據后,會回一條確認信息(ACK),告訴發送方:“我收到了!下一包從xxxx開始發。”
如果發送方遲遲收不到確認,就會懷疑數據丟了。
3. 超時重傳(Timeout Retransmission)
如果一定時間(超時)還沒收到確認,發送方就自動重發。
一般超時時間 = 2 × RTT(往返時延)+ 偏差值。
4. 窗口控制(Sliding Window)
為了提高速度,TCP可以同時發多包,不需要一包一確認。
窗口大小定義了一次可以連續發送多少數據而不用等確認。
小例子:
窗口大小=3,發送方可以連續發第1包、第2包、第3包數據,不用等第1包的確認就發第2包!
5. 快速重傳(Fast Retransmit)
如果連續收到3個相同的ACK(比如一直提示1001未收到),發送方立刻重發缺失的數據段,而不用等超時。
三次握手(建立連接)
- 客戶端發送SYN報文,請求建立連接(SYN=1,seq=J)。
- 服務器收到后,發送SYN+ACK報文,表示接受(SYN=1,ACK=1,seq=K,ack=J+1)。
- 客戶端再回一個ACK報文,確認連接建立(ACK=1,ack=K+1)。
三次握手后,雙方就可以正式通信了。
特別感謝@frozendure繪制的圖片。
四次揮手(斷開連接)
- 客戶端發FIN報文,請求斷開(主動關閉)。
- 服務器收到后,回ACK確認(被動關閉)。
- 服務器數據發完后,也發FIN報文。
- 客戶端收到FIN后,回ACK確認,進入TIME_WAIT等待一段時間后徹底關閉。
小圖示:
為什么是三次握手?為什么是四次揮手?
三次握手的原因
- 防止陳舊連接(老舊、失效的請求包)誤建立連接。
- 確保雙方收發能力正常。
如果只兩次握手,可能因為網絡延遲,服務器誤認為客戶端還想建立新連接,導致資源浪費。假設兩次握手時,A發出的第一個請求連接報文段在某一網絡節點長時間滯留,以致延誤到連接釋放后才到達B。B收到失效的連接請求報文段后,認為是A又發出一次新的連接請求。于是向A發送確認報文段,同意建立連接,此時在假定兩次握手的前提下,連接建立成功。這樣會導致B的資源白白浪費
假設兩次握手時,A發出一個請求報文段,但發送過后A就因為問題而導致下線。之后B收到了A發來的請求連接報文段,給A發送確認報文段,同意建立連接,此時在假定兩次握手的前提下,連接建立成功。這樣會導致B的資源白白浪費
- 第一次握手(客戶端發送SYN):保證客戶端能夠發送數據。
- 第二次握手(服務器發送SYN-ACK):保證服務器能夠接收并發送數據。
- 第三次握手(客戶端發送ACK):保證客戶端能夠接收數據。
四次揮手的原因
- TCP是全雙工,發送和接收需要分別關閉。
- 一方關閉發送,不代表另一方立即也關閉發送,因此需要兩次FIN和兩次ACK,確保雙方都完成通信。
TCP和UDP特點
項目 | TCP | UDP |
---|---|---|
是否連接 | 面向連接(需三次握手) | 無連接 |
可靠性 | 可靠,具備確認應答、重傳機制 | 不可靠,盡力而為 |
傳輸速度 | 較慢(因連接建立和狀態維護) | 較快(無需連接、開銷小) |
傳輸單位 | 字節流(Stream) | 數據報(Datagram) |
是否順序 | 保證順序到達 | 不保證順序 |
占用資源 | 較多(需維護連接狀態) | 較少 |
安全性 | 容易受到SYN洪水攻擊等 | 較少攻擊面 |
優點 | 可靠性高、順序到達 | 快速、資源開銷小 |
缺點 | 速度慢、資源占用高、易被攻擊 | 不可靠、易丟包、亂序 |
適用場景 | 要求高可靠性,能容忍延遲 | 要求實時性強,容忍丟包 |
應用實例 | 文件傳輸(FTP)、發送郵件(SMTP)、網頁瀏覽(HTTP) | 視頻通話(VoIP)、在線視頻直播、網絡游戲、廣播 |
TCP擁塞控制
在 TCP 通信中,如果發送端窗口設置過大,會在短時間內發送大量數據,這可能導致中間路由器和接收端緩沖區被擠爆,進而引發丟包、重傳等問題。TCP 擁塞控制是指通過動態調整數據發送速率,避免過多的數據包涌入網絡,從而引起網絡擁堵甚至網絡癱瘓的一種機制。
因此,TCP 引入了擁塞控制窗口(cwnd),并采用如下四種主要算法動態調整窗口大小:
一、慢啟動(Slow Start)
- 初始化擁塞窗口 cwnd = 1(以 MSS 為單位)。
- 每收到一個確認應答(ACK),就將 cwnd 翻倍(即指數增長)。
- 每經過一個 RTT,cwnd *= 2。
舉例:
- 第一個 RTT:cwnd = 1
- 第二個 RTT:cwnd = 2
- 第三個 RTT:cwnd = 4
- 第四個 RTT:cwnd = 8
? 優點:快速提高網絡利用率
? 缺點:指數增長可能迅速導致擁塞
二、擁塞避免(Congestion Avoidance)
當 cwnd 達到慢啟動閾值 ssthresh
(一般初始值為 65536 字節),就不再使用慢啟動的指數增長,而是進入擁塞避免階段。
- 每經過一個 RTT,僅將 cwnd 加 1(線性增長)。
- 防止窗口增長過快引發網絡擁塞。
舉例:
- cwnd = 64,到達 ssthresh
- 后續每次 ACK,cwnd = cwnd + 1/cwnd ≈ 每 RTT 增加 1
三、超時重傳與慢啟動重啟
如果出現報文段超時未收到 ACK,TCP 認為網絡出現擁塞。
處理方法:
- 將
ssthresh
設置為當前 cwnd 的一半; - 將 cwnd 設為 1;
- 重新進入慢啟動階段。
🔁 這是 TCP 的自我修復機制,避免持續擁塞。
四、快速重傳與快速恢復(Fast Retransmit & Fast Recovery)
如果收到 3 個重復的 ACK(即 ACK 重復了 3 次),TCP 認為某個報文段丟失。
快速重傳行為:
- 立即重傳丟失的段,而不是等待超時。
快速恢復行為:
- ssthresh = 當前 cwnd / 2;
- cwnd = ssthresh + 3(體現網絡尚可);
- 進入擁塞避免階段(不再重回慢啟動);
? 快速恢復保持了中等的發送速率,防止性能大幅下降。
擁塞控制減慢增長速度的條件總結
擁塞控制會減慢增長速度的時機:
- cwnd 超過 ssthresh:
- 進入擁塞避免階段,從指數增長變為線性增長。
- 發生超時重傳:
- 表明網絡嚴重擁塞,立即進入慢啟動(cwnd 重置為 1)。
- 收到 3 個重復 ACK:
- 進入快速重傳,cwmd 縮減并進入擁塞避免。
TCP/IP 數據鏈路層的交互過程簡述
當 IP 層向數據鏈路層(如以太網)傳遞數據時:
- 查找 ARP 緩存:查找目標 IP 對應的 MAC 地址;
- 若存在,直接封裝 MAC 地址;
- 若不存在,發起 ARP 廣播請求;
- 接收到 IP 匹配的設備返回自己的 MAC 地址;
- 使用該 MAC 地址封裝鏈路層幀,完成數據發送。
TCP 和 UDP 如何區分?
傳輸層協議由 IP 協議頭中的 Protocol 字段決定:
- TCP:值為 6
- UDP:值為 17
操作系統根據協議和端口號,將報文傳遞給對應的應用程序。
UDP 中的 connect()
函數原理
connect()
的作用:
- 記錄對端 IP 與端口號;
- 發送數據時不再需要 sendto() 指定地址,可以使用 write()、send();
- 接收數據時只接受來自該對端的數據;
- 可接收異步錯誤信息;
- 丟棄來自其他地址的包。
? 用于長期通信(如 TFTP)或希望使用 TCP 接口風格的場景。
TCP連接中的 TIME_WAIT 狀態詳解
一、TIME_WAIT 狀態如何產生?
- 主動關閉連接的一方(client)發送最后一個 ACK 后進入
TIME_WAIT
; - 保持 2 * MSL 時間后釋放連接;
- MSL(Maximum Segment Lifetime):報文段在網絡中的最大生存時間。
二、TIME_WAIT 的兩個核心作用
1. 確保連接的可靠關閉
- 若最后一個 ACK 丟失,server 會重發 FIN;
- client 能在
TIME_WAIT
狀態中接收該 FIN,并再次回復 ACK; - 保證被動關閉方正常結束連接。
2. 避免舊連接干擾新連接
- 如果不等待,可能使用相同四元組快速建立新連接;
- 網絡中仍存在舊連接的數據包,可能被誤接收,導致數據錯亂;
- 2MSL 等待時間保證舊數據失效。
三、TIME_WAIT 的副作用與優化
- 占用端口資源;
- 影響服務器重啟;
? 解決方法:
設置套接字選項 SO_REUSEADDR
,允許 TIME_WAIT 狀態的端口被重復綁定。
TCP的模型
四層TCP/IP模型如下,包括應用層、網絡層、數據鏈路層、物理層
特別感謝@frozendure繪制的圖片和說明。