TCP和UDP的对比多数情况下被简化为一句话:TCP可靠,UDP不可靠。
单从定义看,这个论断没有错,却把工程上最关键的问题遮住了:’可靠‘与’不可靠‘并非优劣之别,而是一次设计权衡。TCP 取其可靠性,代价是排队与时延;UDP 放弃可靠性,换来响应速度与控制权。二者在加速中要解决的问题因此截然不同:TCP 侧主要处理可靠性附带的时延成本,UDP 侧则要在’不保证送达‘的基础上按需补偿丢包。
两边的加速手段不能混用:把TCP那套逻辑搬到UDP上会伤即时性,把UDP那套搬到TCP上又解决不了窗口增长受限的问题。
TCP的代价:顺序交付与队头阻塞
TCP向应用层提供一个保证:数据按发送顺序到达,不丢、不重、不乱。为了维持这个保证,TCP在协议栈内部做了几件事。
接收端维护着一个重排序缓冲区。IP 网络里乱序极为常见——不同的包完全可以经由不同路径抵达;只要到达次序与发送次序不一致,接收端就必须等缺失的那个包补齐,才能把后续数据交给应用层。这便是队头阻塞(Head-of-Line Blocking):一个丢失的包,阻塞了其后所有已经到达的包的交付。
队头阻塞的伤害与 RTT 成正比。以 RTT 等于 200ms 为例:丢一个包,接收端至少 200ms 后才能收到重传;这段时间内,随后到达的数据包全部被扣在缓冲区。应用层观测到的不是’200ms 后逐步恢复‘,而是’200ms 静默,随后数据集中涌出‘。换算到具体现象:网页上某个资源卡住后突然完成;而对实时应用来说,200ms 前的游戏状态已经失去意义,这是难以接受的。
TCP 的第二项开销源于拥塞控制的保守设计。慢启动时窗口呈指数增长看似迅猛,但逼近链路容量后,基于丢包的算法会主动制造丢包来探测上限,然后削减窗口重新爬升。短 RTT 链路上这个循环很快;长 RTT 链路上,每经历一次丢包,都要多个 RTT 才能重新回到满速率。
加速器如何介入TCP
TCP加速器的核心逻辑是:把TCP的代价隔离在短RTT段内。
把端到端的 TCP 拆成两段之后,每段的 RTT 都会显著缩短,用户至加速节点这一段通常只有直连时的 1/3 到 1/4。队头阻塞依旧存在,但持续时间与 RTT 成正比——RTT 越短,恢复越快。窗口恢复同样被压缩:原本在 200ms RTT 上需要 2 秒完成的窗口爬升,在 50ms RTT 上 0.5 秒即可完成。
需要注意的是,拆分也会引入新的变量:两段 TCP 各自独立,拥塞状态互不可见。用户到节点这一段若带宽充裕,窗口会一路冲高;节点到目标这一段若正在排队,窗口则被压制。数据于是高速涌入节点,堆积在其发送缓冲区中。一旦堆积量超过’节点至目标‘链路的带宽延迟积,额外的排队时延就在加速器内部被制造出来了。
这意味着,加速器的有效运作要求节点的缓冲区管理调度策略与两段线路链路的带宽差异匹配。假如入口线路链路远快于对外出口线路链路(比如用户是千兆宽带,对外出口线路链路源头在于跨洋而只有几十Mbps的有效吞吐量),节点必须主动向客户端施加反压——通过调整TCP窗口或ping 值ACK来降低入口段的发送速率。不做这个优化的加速器,会在节点内部制造自己的拥塞点。
UDP的设计:不保证,不阻塞
UDP向应用层提供的是一个完全不同的契约:数据报尽力交付,不保证到达,不保证顺序。假如数据报丢失,UDP不再送一次。假如数据报乱序,UDP不重排。应用层收到什么就是什么,UDP不替应用做任何决定。
恰是这个’把决定权交给应用‘的设计,让大量实时应用选择了 UDP。游戏、VoIP、实时视频这些场景,对时效性的要求高于对完整性的要求:语音包丢失时,应用宁可听一小段静音,也不愿等到 200ms 之后把已经过时的音频插回当前进度;游戏的位置更新丢了一包也无所谓,只要更新够密,下一个包会在几毫秒之内把它覆盖掉。
UDP把可靠性决策权交给了应用层。应用可以做到自己实现选择性再送一次(只再送一次关键数据包),可以做到实现FEC(用冗余换丢包恢复),也可以做到什么都不做(容忍丢包)。这种灵活性是UDP在即时场景中的核心价值。
但UDP在公网上有一个结构性的劣势:网络中间设备对它的态度。
拥塞发生时,路由器队列管理的天平通常倾向 TCP。以 WRED 为代表的主动队列管理算法会有选择地丢弃 UDP 包,因为 UDP 不会像 TCP 那样收到拥塞信号后降低发送速率。不减速的 UDP 流在拥堵链路上会被标记为’不合作的流量‘并优先丢弃。数据上表现为:高峰时段 UDP 的丢包率通常高于 TCP——原因不是 UDP 更脆弱,而是设备策略在设计上优先保障 TCP 的公平性。
加速器对UDP能做什么

UDP加速不得要拆分连接,源头在于UDP没有连接。UDP加速不得要管理拥塞窗口,源头在于UDP没有窗口。那么加速器在做什么?
路径选择仍然是第一位的。假如加速器能将UDP数据包从一条丢包率2%的公共路径迁移到一条丢包率0.2%的私有骨干网路径,加速成效直接体现在应用层的丢包减少上。这部分逻辑和TCP加速相同,但对UDP的收益往往更一眼看得出来——源头在于UDP对丢包没有自愈能力,丢一个就是一个。
在这条更优的路径之上,加速器可以做到在两端节点之间增加FEC。发送端在连续N个数据包后附加M个冗余包,使得接收端在N+M个包中任意丢失不超过M个时都能完整恢复。FEC不消除丢包——物理线路链路上的数据包仍然在丢失——但它让应用层感知到的丢包率降到零。
FEC 的成本可以用两个数来量化:带宽开销与编码时延。发送端必须累积到一定数量的数据包才能生成冗余包——对高频小包(例如每秒 60 个更新包)影响很小,累积 4 个包约需 67ms;低频流量则可能等待更久。这段累积时间叠加编码运算本身的耗时,构成了加速器额外引入的处理延迟。
在工程实践中,经常观察到一个权衡:开启FEC后,游戏内显示的丢包率往下掉,但基础ping值增加了3-5ms。对大多数玩家来说,丢包率从1%降到0带来的体验优化远大于ping值增加5ms的代价。但对于对ping 值极度敏感的场景(比如职业电竞),这个权衡得要被明确意识到。
误判:QUIC与”UDP加速”
QUIC是一个基于UDP的传输协议,它在应用层实现了类似TCP的可靠传输和拥塞控制。很多加速服务声称支持”UDP加速”,但实际测试会发现它们对QUIC的处理并不一致。
一些加速器将QUIC用量当作普通UDP处理——单纯转发,不做FEC,不做路径优化。这是合理的,源头在于QUIC已经内置了拥塞控制和丢包恢复,外部的FEC可能干扰QUIC自身的速率调节逻辑。但假如加速器对QUIC什么都不做,用户看到的效果就和直连没有区别(除了路径可能不同)。
另一些加速器会尝试对QUIC用量也做TCP式的分段中继——终结QUIC连接,在内部用自定义协议传输,到对外出口节点再重建QUIC连接。这种做法等于破坏了QUIC的从头到尾加密和认证模型,多数情况下得要客户端安装根证书才能中间人解密。对用户来说,带来的安全风险可能超过加速收益。
一个更容易混淆的情况是,加速器宣称”UDP加速”,但实际只优化了特定端口的UDP用量(比如常见的游戏端口),而对QUIC使用的443端口的UDP用量走的是另一套逻辑(甚至可能被降级为直连)。用户在打一次测速时看到UDP加速有效,但在使用QUIC的应用(比如基于HTTP/3的网站、某些视频流)时感受不到优化,源头就在这里——两种UDP用量经过了不同的处理管道。
# 确认某个应用使用的UDP端口和协议 # QUIC多数情况下使用UDP 443 ss -tunlp | grep 应用进程名 # 抓包观察UDP用量的行为模式 # QUIC的包多数情况下较大,且有TLS握手的特征 tcpdump -i eth0 -n udp port 443 -c 50
协议的边界与选择
归纳起来,TCP 与 UDP 在加速上的分野,根源是它们对应用层的承诺不同。TCP 承诺可靠且有序,加速器因此只能通过分段把这些承诺附带的时延隔离出去;UDP 不作任何承诺,加速器的自由度看似更大,实则更受限——不能假定包的语义、不能重排顺序、不能随意加延迟,只能在路径优化与轻量冗余的范围内活动。
这个差异也决定了匹配关系:网页与 API 调用依赖 TCP,优化重点是握手时延与窗口爬升时间;游戏与实时通信依赖 UDP,优化重点是丢包率与路径抖动。把按 TCP 设计的方案(例如强制分段中继)套用到 UDP 流量上,结果要么破坏其实时性,要么因协议不匹配而根本连不上。
反过来,假如试图用UDP的”尽力而为”逻辑去加速TCP——比如只做路径转发不做连接分段——那等于放弃了所有TCP层面的优化可能,退化为一个纯粹的VPN。
把握两个协议的设计取舍,目的不是背下一张特性对照表,而是拿到一个加速方案时,能够判断它的核心逻辑围绕哪个协议构建,以及它与你流量类型的匹配程度。两者不可互换,而多数用户并不清楚自己在用哪一个。相比直接对比各家公布的延迟数字,先查清自己流量的协议构成更有参考价值。