QUIC(Quick UDP Internet Connections)是由 Google 設計并被 IETF 標準化的傳輸層協議,它基于 UDP 實現,但提供了類似 TCP 的可靠性和更高級的功能(如多路復用、0-RTT 握手、TLS 加密等)。
盡管 UDP 是不可靠的,QUIC 實現了自己的機制來提供:
? 可靠傳輸、順序保證、流控、擁塞控制、加密通信
🚀 一句話理解:
QUIC 在 UDP 之上自己造了一個“更好的 TCP”,通過用戶態實現可靠傳輸。
🧩 QUIC 如何在 UDP 上實現可靠傳輸?
下面是 QUIC 提供可靠性的核心機制:
? 1. 數據分片與多路復用(Streams)
-
QUIC 使用 Stream 概念將數據拆分成多個邏輯流,每個流有自己的 ID 和順序控制。
-
每個數據包中可能包含多個流的數據片段。
-
每個 Stream 保持自己的有序性和重傳機制,互不影響,解決了 TCP 的“隊頭阻塞(Head-of-line blocking)”問題。
? 2. ACK 機制與重傳
-
每個 QUIC 包都有一個唯一的包序號(Packet Number)。
-
接收方會通過 ACK frame 顯式告訴發送方收到了哪些包(可能是一個范圍段,例如
ACK [5,6,7,9]
)。 -
發送方根據 ACK 結果進行 選擇性重傳(Selective Retransmission),而不是像 TCP 那樣使用窗口回退(Go-Back-N)。
? 3. 流控(Flow Control)
QUIC 實現了兩級流控:
類型 | 控制內容 |
---|---|
連接級流控 | 控制整個連接中所有數據的大小 |
流級流控 | 控制單個 Stream 可發送的字節量 |
避免發送方淹沒接收方,防止內存爆炸。
QUIC 實現流控(Flow Control)是為了防止發送方發送太多數據而壓垮接收方的內存,確保 發送速度與接收能力匹配。
QUIC 的流控機制比 TCP 更靈活,它支持:
連接級流控(Connection-level) + 流級流控(Stream-level)
? 一句話總結:
QUIC 使用
MAX_DATA
和MAX_STREAM_DATA
幀,讓接收方“顯式告訴”發送方它還能接受多少數據,從而實現精細的流控。
🔍 QUIC 的兩個流控層次
類型 | 控制范圍 | 控制方式 |
---|---|---|
連接級流控 | 控制整個連接總共能發多少數據 | 使用 MAX_DATA 幀通知 |
流級(單條流)流控 | 控制某條 stream 能發多少數據 | 使用 MAX_STREAM_DATA 幀通知 |
🧩 工作機制詳解
1. 🚦 初始窗口(Initial Flow Control Window)
-
每當連接或某個 stream 建立時,接收方通過
Transport Parameters
告訴發送方:initial_max_data = 65536 # 整個連接最多能發 64KB initial_max_stream_data = 32768 # 每個 stream 最多能發 32KB
2. 📤 發送方:按窗口大小發數據
-
每個 packet 中的數據都有位置偏移(offset)
-
發送方不能發送超過
offset > max_data
的內容 -
如果快達到限制,就暫停發送,等接收方“放行”
3. 📥 接收方:接收 + 消費數據后,發送 MAX_*
幀
當接收方:
-
消費了部分數據(應用層讀取了),或者
-
有更多緩沖空間
就會發以下幀通知發送方放寬限制:
幀類型 | 作用 |
---|---|
MAX_DATA | 提高連接級可發送總量 |
MAX_STREAM_DATA | 提高某個 stream 的可發送數據量 |
📝 例子:
MAX_STREAM_DATA(StreamID=5, MaximumData=64000)
MAX_DATA(MaximumData=128000)
4. 🚧 如果發送方超過限制會怎樣?
-
接收方會直接 丟棄該數據包
-
并可能發送
FLOW_CONTROL_ERROR
幀,強制斷開連接
🔁 動態調整窗口(流控窗口增長)
QUIC 支持動態調整窗口大小,類似 TCP 的“滑動窗口”機制,但更靈活:
-
接收方可以基于自身處理速度、緩沖區情況等策略動態調整
-
應用層可參與窗口策略調整(QUIC 是用戶態協議)
📊 示例圖:QUIC 流控流程簡圖
[Sender] [Receiver]│ ││───── Data (offset: 0~32767) ─────?│ ? 在窗口范圍內│───── Data (offset: 32768~65535) ─?│ ? 超出流窗口限制│ ││?───── MAX_STREAM_DATA (64000) ────│ ? 允許再發更多
? 總結:QUIC 的流控機制比 TCP 更靈活的地方
特性 | TCP | QUIC |
---|---|---|
支持多路復用下的流控 | ? 需應用層實現 | ? 原生支持 per-stream 流控 |
流控信息粒度 | 每個連接一組窗口 | 每個流都有單獨窗口 |
流控窗口通告方式 | 被動通告(ACK + 窗口值) | 主動通告(MAX_* 幀) |
動態擴展 | 有,但實現不易 | 簡潔靈活,用戶態易擴展 |
? 4. 擁塞控制(Congestion Control)
-
QUIC 可復用 TCP 的擁塞控制算法(如 Reno、CUBIC、BBR 等)。
-
因為 QUIC 完全在用戶態,所以可以快速升級/切換擁塞算法,而不需要內核修改。
? 5. 加密與握手(TLS 1.3)
🧵 四、多路復用避免隊頭阻塞,加速整體數據流
TCP 中多個邏輯流復用一個連接時,某個小包丟失可能導致整個流被阻塞(隊頭阻塞)。
QUIC 的解決方式:
📶 五、QUIC 支持連接遷移,減少斷線重連時間
🔚 小結一句話:
QUIC + UDP 快的根本原因在于它跳過了 TCP 的繁瑣握手、內核開銷和流阻塞,通過用戶態協議 + 0-RTT 加密通信讓“發第一個字節”變得更快。
? 總結對比表
項目 | TCP + TLS | QUIC + UDP |
---|---|---|
握手延遲 | 至少 1~2 RTT | 最快 0-RTT,首次僅需 1 RTT |
加密 | TLS 分層 | 內建 TLS 1.3,第一包就加密 |
隊頭阻塞 | 存在 | 消除(Stream 級別傳輸) |
連接狀態 | 內核態管理 | 用戶態管理,效率高 |
多路復用 | 需要上層協議實現 | 協議原生支持 |
連接遷移 | 不支持 | 原生支持 Connection ID 遷移 |
適合移動網絡 | 一般 | 非常適合(連接遷移 + 0-RTT) |
-
所有 QUIC 數據包(除了第一個)都是 強加密 的。
-
基于 TLS 1.3 實現握手和密鑰協商,合并傳輸和加密握手,支持 0-RTT 和 1-RTT 連接建立。
-
避免了 TCP + TLS 的多輪握手,提高首次連接速度。
-
🔍 詳細原因分析(按階段分解)
🟡 一、TCP + TLS 的握手流程 = 至少 3 次往返
傳統的 TCP 連接建立 + TLS 加密握手如下:
1. TCP 三次握手(1.5 RTT):Client → SYNServer → SYN-ACKClient → ACK2. TLS 1.2(或 1.3)握手(再來 1~2 RTT)3. 才能發送加密數據
即:首次連接至少耗時 1~2 RTT(往返時間)
🟢 二、QUIC 將 握手和加密合并在一次往返中
QUIC 的握手流程使用 TLS 1.3 直接集成在傳輸協議中:
-
首次連接(1-RTT):
-
Client → Initial Packet(攜帶 TLS Client Hello) ← 第一次發包就帶加密握手← Server Hello + 加密信息(+ 證書等) Client → Finished(+ 應用數據)
-
重連(0-RTT):
-
Client → 數據 + 加密握手(直接發數據!) ← ★ 零延遲
👉 QUIC 可以實現 “0-RTT 數據傳輸”,幾乎是立即發送第一條消息。
🔧 三、UDP 不需要內核狀態建立連接,QUIC 在用戶態實現更靈活
-
TCP 是 面向連接的:需要在內核里維護連接狀態(socket 狀態機)。
-
UDP 是無連接協議,QUIC 在用戶態自己管理連接狀態,避免了內核/用戶態頻繁切換。
-
用戶態連接管理允許更快的上下文切換、更容易多路復用。
-
每個 stream 有獨立的傳輸/重傳機制
-
某一 stream 丟包不會阻塞其他流,數據能更快抵達
-
QUIC 連接綁定在 Connection ID,而不是 IP + Port
-
移動設備換網(如從 Wi-Fi 切 4G)時無需重新建立連接,延遲更小
? 6. 包編號與重排重組
-
QUIC 的包編號是嚴格遞增的,不可重用。
-
即使包亂序到達,也可通過包號重排序。
-
QUIC 自己實現了類似 TCP 的
SACK(Selective ACK)
功能。?
? 7. 頭部校驗和加密保護
-
包頭也經過加密處理,防止中間人攻擊(如修改流量控制字段等)。
📦 總結:QUIC 如何在 UDP 上“可靠傳輸”
技術點 | 實現作用 |
---|---|
Stream(多路復用) | 消除隊頭阻塞、實現數據隔離 |
Packet Number + ACK | 保證數據到達與丟包檢測 |
重傳機制 | 實現可靠交付 |
流控 + 擁塞控制 | 限制數據發送速度,防止擁堵 |
TLS1.3 加密 | 確保安全性和身份驗證 |
用戶態實現 | 更靈活,可快速迭代 |
📌 簡圖:QUIC vs TCP(在可靠性層面)
┌──────────────┐ ┌──────────────┐│ 應用層 │ │ 應用層 │└────┬──────▲──┘ └────┬──────▲──┘▼ │ ▼ │┌──────────────┐ ┌──────────────┐│ QUIC 協議 │ │ TCP 協議 │└────┬──────▲──┘ └────┬──────▲──┘▼ │ ▼ │┌──────────────┐ ┌──────────────┐│ UDP/IP │ │ IP層 │└──────────────┘ └──────────────┘
QUIC + UDP 連接更快,是因為它在 連接建立階段(握手)和數據傳輸機制方面做了大量優化,特別針對 TCP 的延遲瓶頸進行了設計改進。
? 簡要結論:
QUIC 比 TCP 快,主要因為它省掉了握手輪次 + 消除了 TCP+TLS 分層帶來的延遲 + 更高效的連接復用。