← 返回文章列表

TCP 与 UDP 怎么选:可靠性、顺序与延迟的取舍

网络协议网络

五个维度看清差异

维度TCPUDP
连接面向连接(握手 + 状态)无连接,每个数据报独立
可靠性确认、重传、按序交付不保证送达,也不保证顺序
拥塞控制内建,会主动降速没有,需要自己在应用层实现
头部开销20 字节以上(含选项更多)8 字节
延迟表现丢包时等待重传,延迟抖动大不等重传,抖动小但可能丢数据

什么时候选 UDP

  • 实时音视频:晚到的数据包没有意义,宁可丢也不等;
  • 在线游戏:状态频繁更新,最新一帧比补旧帧重要;
  • 短查询:如 DNS,一次往返完事,重传由应用层控制更简单;
  • 自定义传输:QUIC 就是在 UDP 之上重建了一套更现代的传输机制。

什么时候必须用 TCP

  • 文件、数据库、消息:任何「一个字节都不能少」的场景;
  • 需要严格顺序:如日志流、复制通道;
  • 不想自己造轮子:重传、拥塞控制与粘包处理都很复杂,能用现成的就别自己写。

在 UDP 上要自己补的四件事

  1. 序号:用于检测丢失与乱序;
  2. 重传策略:什么时候重传、重传几次后放弃;
  3. 拥塞控制:否则会在弱网下把链路打满,影响所有业务;
  4. 分片与 MTU:超过 MTU 会在 IP 层分片,丢一片即整包作废,应在应用层控制报文大小。

常见误区

  • 「UDP 会丢包所以不能用」:错。关键是业务能否容忍丢包,以及你是否在应用层做了补偿;
  • 「UDP 一定更快」:不一定。省下的是握手与队头阻塞,但若你在应用层重做了重传,往往还不如直接用 TCP;
  • 「TCP 不会丢」:TCP 只是负责把丢的包补回来,应用层仍可能超时,且超时时长由重传决定。

一个常被忽略的细节:消息边界

TCP 是字节流,没有消息边界:多次 send 的数据可能被合并或拆分,应用层必须用长度前缀、分隔符或固定结构自行组帧。UDP 保留数据报边界——一次发送对应一次接收,但这也要求每个报文自成一体,不能依赖前后报文拼装。

与 HTTP/3 的关系

HTTP/3 基于 QUIC,而 QUIC 建立在 UDP 之上。它这样做的目的不是「不要可靠性」,而是把重传、拥塞控制与 TLS 放进同一层,既保留可靠传输,又避免了 TCP 的队头阻塞——一个包丢失时不会卡住所有流。

常见问题

做内网 RPC 用哪个?除非你有成熟的传输层经验,否则用 TCP(或 HTTP/2、gRPC)。实时对战游戏用 TCP 会怎样?丢包后的重传等待会让操作明显发涩,这正是它们选择 UDP 的原因。如何测试 UDP 质量?关注丢包率、抖动与乱序率三项,而不只是带宽。

哪些应用层协议跑在 UDP 上

  • DNS:默认 UDP 53,响应过大或需要可靠传输时回退 TCP 53,这也是“某些域名查询特别慢”的原因之一;
  • QUIC / HTTP3:基于 UDP 自行实现可靠性与拥塞控制,必须放行 UDP 443;
  • 实时音视频:RTP 走 UDP,宁可丢帧也不重传,重传带来的延迟比丢包更难忍受;
  • VPN 与隧道:WireGuard 用 UDP,需注意部分网络会限速或封禁 UDP。

迁移到 QUIC 的注意点

  • 确认中间设备放行 UDP 443,并对被拦截的客户端保留 HTTP/2 回退;
  • HTTP/3 的连接迁移依赖连接 ID,NAT 超时较短时需相应调整保活;
  • 监控回退比例与握手失败率,这两项最能反映实际可用性。

选型时的三个问题

一是“丢一个包要不要重发”?必须重发就用 TCP;二是“能不能接受建立连接的开销”?短连接小请求密集时,连接复用比协议选择影响更大;三是“中间设备会不会拦”?UDP 在部分企业网络中受限,设计时就要准备 TCP 回退路径。