Skip to content

UDP 实现可靠传输

约 861 字大约 3 分钟

2025-12-18

image 想要基于 UDP 实现可靠传输,可以参考 TCP 可靠传输的特性,如:序列号、确认应答、超时重传、流量控制、拥塞控制

QUIC

基于 UDP 协议实现的可靠传输方案

实现

要基于 UDP 可靠传输,运输层是无法依靠的了(靠运输层的不就是 TCP?),只能从应用层入手 在 HTTP3 中,其基于 UDP 报文封装了 QUIC 协议的头部 image

QUIC Packet Header

QUIC 包的头部分为两种

  • Long Packet Header 用于首次连接
  • Short Packet Header 用于后续连接 image Long Packet Header 主要用于三次握手以协商出连接 ID,在协商出 ID 后双方只需要锚定这一 ID 便能唯一确定逻辑传输的通道 Packet Number 是每个报文独一无二的编号,他是严格递增的,即便发生了重传,重传的报文也会赋予一个新的编号

在 TCP 中,重传的数据包所携带的编号与原数据包是一致的,这会造成客户端无法准确识别出接收到的数据包是原始包还是重传包,影响 RTT 的采样,进而影响 RTO 的计算

QUIC Frame Header

一个 Packet 中可以存放多个 QUIC Frame image 每一个 Frame 可以认为就是一条 HTTP 请求,Stream ID 用于区分并发的 HTTP 请求,一个请求可能会被分为多个部分进行传输 Offset 类似于 TCP 中的 Seq 序列号,保证数据的顺序性用于数据的重组 Length 指明了 Frame 的长度

流量控制

在 TCP 中,若出现了丢包会等待那个丢失的包重发接收后才会滚动窗口 在 QUIC 中,每一个请求的数据会被包装为一个 stream,若出现 packet 丢失,即该 packet 中的 stream都丢失了,不会影响后续 packet 中的 stream 的读取,解决了 TCP 中的头部阻塞问题

QUIC 实现

QUIC 中并不像 TCP 一样存在滑动窗口字段,而是基于信用的流量控制机制 即通过通告一下两个字段实现

  • MAX_DATA:控制整个连接最大字节数
  • MAX_STREAM_DATA:控制某个某个 stream 的最大字节数 对于某个 stream image 接收方通告MAX_STREAM_DATA(stream_id=1, max_stream_data=65536),表示该 stream 上的最大接收窗口为 65536 字节 接收窗口 = 最大接收窗口 - 接收到的最大offset已收到且被上层读取的数据达到最大接收窗口的一半时,将会移动最大接收窗口 image

拥塞控制

QUIC 默认使用了 TCP 中的 Cubic 拥塞控制算法,即:慢开始、拥塞避免、快速重传、超时重传

特性

连接迁移

TCP 通过四元组确定一个唯一的连接 QUIC 通过在连接初次建立时协定的目标连接 ID脱离四元组的锚定,只要携带的 ID 相同,无论 ip 如何改变都能够确定连接的双方

更快的连接建立

QUIC 内部包含了 TLS,仅需 0 RTT 完成连接与加密的连接? image

参考

如何基于 UDP 协议实现可靠传输?

#review