跳到主要内容

VPN 在纸面上看似很快,实际用起来却糟糕透顶:网页停几秒后一下子全涌出来;下载先冲刺,又爬行,再冲刺;本该一分钟传完的文件要十分钟。测速在短暂的突发期间甚至能给出像样的数字。如果这种现象只出现在某种模式下,或者只出现在差的网络上,一个可能的原因是一个设计问题,它有个很出名的外号:TCP-over-TCP。

本文讲清楚 TCP-over-TCP 到底是什么,为什么两层本意都是帮忙的机制会合成一种缓慢,症状是什么样,以及普通用户能做什么。这不是协议选购指南。若想把一种常见隧道的两种传输方式并排比较,可以读 OpenVPN 的 TCP 与 UDP 对比;本文的重点是原理和诊断。

简要回顾 TCP 与 UDP

TCP 和 UDP 都在两台计算机之间传输数据,但它们承诺的东西不一样。

  • TCP 给数据编号,确认已收到的内容,重发缺失的部分,按顺序交付,并在认为网络拥塞时放慢速度。它是网页、邮件和文件下载背后那种可靠而“有礼貌”的传输方式。
  • UDP 只管发送数据包,不确认、不重发、不排序。包丢了它也不管。需要可靠性的话,必须由上层应用自己补上。

你日常的大部分流量是 TCP。VPN 隧道是承载这些数据包的第二层。隧道本身也可以选择自己的传输方式:有的用 UDP 发包,有的用 TCP。如果你的普通流量是 TCP,而隧道也是 TCP,就形成了 TCP-over-TCP。隧道各部分如何拼合的更多背景见 VPN 协议是什么。

问题出在哪里:一个坏包,两支维修队

可靠性是 TCP 的全部意义所在,而一旦发生两次,就成了问题。设想在你与 VPN 服务器之间丢了一个包。

外层隧道先发现。 隧道的 TCP 连接看到一个空缺。它会停止交付空缺之后的所有数据,即使这些数据已经到达,因为 TCP 承诺按顺序交付。它等待缺失的那片数据,然后重发。这期间隧道里随后的每个包都在队列里等着。

内层连接也发现了,只是更晚。 对隧道内正在下载网页的连接来说,确认消息没有按时返回。它的重传计时器到期,这告诉它网络拥塞了。它做出两种反应:把数据再发一遍,并大幅降低发送速率。

结果就是叠加堆积。

  1. 外层还在修复第一次丢包。
  2. 内层已宣布数据丢失,并发出了副本。
  3. 这个副本进入外层队列,排在正在被修复的那个包后面。
  4. 于是隧道里装着没人需要的重复数据。
  5. 内层看到延迟和重复确认,把发送窗口缩得更小。

每一层都遵守自己的规则,行为正确。但合在一起就浪费容量并造成停顿。严重时,内层的重传计时器在反复超时后不断翻倍,于是连接越来越慢,这种情形有时被称为 TCP 崩溃。

一个具体的时间线

设想一条往返 60 毫秒的普通链路,隧道里正在传一个下载,并且丢了一个包。

时间 外层隧道(TCP) 内层连接(TCP)
0 ms 隧道的第 7 个包丢失 持续发送数据流
60 ms 第 8、9、10 个包到达,但被扣住 等待确认
120 ms 接收端发出缺口信号 确认迟到
200 ms 外层重发第 7 个包 计时器触发,内层重发数据
260 ms 第 7 到 10 个包一次性放出 内层看到突然的涌入和重复
300 ms 内层的副本排在原件后面到达 内层窗口已经减半

在这个简化的图景里,一个丢包大约耗费了 200 到 300 毫秒,之后发送速率还降低,另外还有重复数据。在丢包率 0.01% 的干净链路上,这种事很少发生,你注意不到。在丢包率 2% 的 Wi-Fi 链路上,它每秒发生许多次,吞吐量下降的幅度远大于丢包数字本身所暗示的。

为什么 UDP 隧道能避开这个问题

如果隧道跑在 UDP 上,可靠性层就只有一个:内层的 TCP 连接。隧道的包丢了就是丢了,隧道里没有什么会扣住其余数据。内层连接以正常方式发现缺失数据,只修复一次。大多数现代隧道设计就是这样工作的,这也是网络允许时通常优先选择 UDP 的原因之一。WireGuard 项目就是只跑在 UDP 上的隧道设计的一个例子。

更新的设计走得更远。RFC 9000 定义的 QUIC 传输跑在 UDP 之上,并内置自己的丢包恢复,这也是为什么像Proxying IP in HTTP这样的一些 IP-in-HTTP 方案可以通过 HTTP/3 承载隧道,而不必叠加两层 TCP。你不需要了解细节,关键是业界有意地从 TCP-in-TCP 退了出来。

为什么 TCP 隧道仍然存在

既然这么别扭,为什么还提供?因为它解决的是另一个问题。

  • 有些网络限制 UDP。 某些公司、学校、酒店和公共网络只放行范围很窄的一类流量。TCP 隧道有时能在 UDP 隧道无法工作的地方工作。
  • 有些设备对 UDP 的处理不佳, 比如较旧的路由器 UDP 超时很短,会掐断空闲的隧道。
  • TCP 模式是后备方案。 许多 VPN 应用只在首选模式失败时才用它。

这是对权衡的正当使用,而不是违反规则的花招。如果你的网络被设置为只允许某些流量,请尊重这项政策,工作上确有需求时,请与网络所有者沟通。使用 TCP 隧道的代价就是本文所述的可能变慢,所以它通常是第二选择。

识别症状

TCP-over-TCP 的麻烦很少自报家门。下面这些表现值得怀疑,尤其是当它们出现在较差的网络上、在好的网络上又有所改善时。

  • 短时测试吞吐量看着不错,长时间传输却骤降。
  • 速度呈锯齿状摆动,中间有很长的平坦段。
  • 页面冻结几秒,然后一下子全部加载。
  • 交互式任务,比如在远程命令行里打字,会一阵一阵地延迟。
  • 在 Wi-Fi 或移动数据上比有线网络严重得多。
  • 到 VPN 服务器的 ping 时间看起来正常,真正的传输却表现很差。
  • 同一台设备换个网络或换个模式就更快。

如果你遇到的是持续的慢而不是停顿,请先读为什么 VPN 会慢,因为距离或服务器繁忙这类简单原因比 TCP-over-TCP 常见得多。

不用特殊工具如何测试

在大多数手机上你看不到隧道内部,但可以做一次对照实验。

第 1 步:先让网络健康。 对路由器 ping 100 次(Windows 用 ping -n 100,macOS 或 Linux 用 ping -c 100)。如果有丢包,先解决它,因为丢包才是问题的触发器。

第 2 步:记录没有 VPN 时的基线。 下载一个大的公共文件,或者做一次测速,记下耗时以及速度是否平稳。

第 3 步:开着 VPN 做同样的测试。 比较数字,也比较曲线的形状。平滑但略低的线是正常的隧道开销,带停顿的锯齿线才是可疑的表现。

第 4 步:只换网络。 试试网线、另一个 Wi-Fi 频段或移动数据。如果在干净的链路上锯齿消失,说明隧道加丢包共同造成了问题,这符合上述模式。

第 5 步:查看应用使用的模式。 如果应用显示连接类型,记下是 TCP 还是 UDP。如果没有显示,就不要猜测。使用 XPASS 时,你用的是免费的 VPNclient 应用以及 My Pass 页面上的信息;除非支持人员建议,否则请保留应用的默认设置。

第 6 步:换一个位置。 另一台服务器可能走更干净的路径,丢包减少,影响也就随之减轻。

减轻影响的实用办法

  1. 从源头减少丢包。 用网线,靠近路由器,选 5 GHz,停掉大量上传。丢包是触发条件,消除它就消除了大部分痛苦。
  2. 网络和应用允许时优先 UDP。 这是许多现代隧道设计的默认选项。只有当应用明确提供选择时才切换。
  3. 选更近的位置。 往返时间短,意味着计时器更快到期、恢复更快。
  4. 让 MTU 合理。 过大的数据包可能在原有问题之上增加丢包和分片。测量方法见如何找到合适的 MTU。
  5. 避免叠加隧道。 在一个 VPN 之上再跑一个 VPN,或者经过同样使用 TCP 的代理,会让层数成倍增加。
  6. 长时间停滞后重新连接。 新会话会清除已经膨胀的计时器。
  7. 检查软件冲突,比如会检查流量或代理流量的安全套件。

如果你的网络只允许 TCP,而你仍需要 VPN,就接受一定程度的变慢。降低负载,例如暂停大文件下载,会让情况更容易忍受。

局限与提醒

  • 并非每个慢的 VPN 都有这个问题。 距离、服务器负载、设备较弱和运营商限速要常见得多。
  • 现代 TCP 比教科书里的图景更聪明。 调优、发包节奏控制和更好的丢包恢复缓解了最坏的影响,所以损害程度因操作系统而异。
  • 有些隧道产品用自己的办法减轻这个问题, 比如小缓冲或自定义可靠性机制。不同实现的结果不同。
  • 你不一定能看到传输方式。 许多应用把它隐藏起来。没有证据就不要假定原因。
  • TCP 隧道并不不安全。 问题在性能,不在安全。加密是另一项特性,见VPN 协议是什么。
  • 不要为了规避网络规则而改设置。 如果单位或学校限制流量,请询问所有者。

常见错误

  • 以为 TCP 隧道比 UDP 隧道更安全或更可靠。
  • 只根据传输的前十秒判断性能。
  • 只在信号弱的 Wi-Fi 上测试,就责怪 VPN 的设计。
  • 同时更改隧道模式和位置,结果不知道哪个起了作用。
  • 忽略丢包,把别的地方都调了一遍。
  • 连接已经停滞,却放着不管好几分钟,而不是重新连接。

总结

当 TCP 流量被放进同样是 TCP 的隧道里传输,就产生了 TCP-over-TCP。数据包丢失时,外层和内层都会去修复,扣住流量、发出重复数据并降低各自的速度,造成停顿以及呈锯齿状的缓慢传输。在干净的连接上影响很小,在丢包的连接上可能很大。基于 UDP 的隧道避免了这种叠加,而 TCP 隧道作为限制 UDP 的网络的后备方案继续存在。最好的防御是消除丢包、使用默认模式、选择更近的位置,并在改动任何东西之前先测量。

如果想用一个短期预付套餐比较不同网络的表现,可以在价格页面了解套餐如何运作。

常见问题

TCP-over-TCP 是什么?

指你平常的 TCP 流量,比如网页或下载,被放进一条本身也跑在 TCP 上的 VPN 隧道里传输。这样内层连接和外层隧道各自都有一套可靠传输和重传逻辑,两者可能互相干扰。

为什么 TCP-over-TCP 会慢?

数据包丢失时,外层先修复并扣住后面的所有数据,内层也察觉到延迟,可能把同样的数据再发一遍并降低自己的发送速率。重复修复和叠加的计时器会造成停顿、突发和低吞吐,尤其是在本来就丢包的链路上。

TCP 模式的 VPN 一定不好吗?

不是。在干净、丢包很少的连接上,影响可能很小,感觉不到。在 Wi-Fi 信号弱或移动网络繁忙这类丢包、拥塞的链路上才会变得严重。当网络限制 UDP 时,TCP 模式有时是唯一可用的选项,所以这是一种权衡,而不是错误。

怎么知道我的 VPN 用的是不是 TCP?

如果应用提供了连接或协议信息,就去那里查看,或者查看服务方提供的设置说明。应用没有显示的话,请保留默认设置并咨询支持。没有理由就不要改连接设置。

避免 TCP-over-TCP 最好的办法是什么?

网络允许时优先选择走 UDP 的隧道,并通过解决 Wi-Fi 或运营商丢包问题来保持底层连接健康。如果应用正在使用默认模式,就保持原样,先换一个网络测试,再考虑改动。

关于作者

Bob Kanokphon Thongdee,XPASS VPN 创始人

Bob Kanokphon Thongdee

  • XPASS VPN 创始人
  • eSIMonline.asia 联合创始人
  • 7 年以上网络营销经验
  • Cojourney Visa 与 Cojourney Travel 创始人

短途出行或忙碌的一个月,需要 VPN?

XPASS 提供按天数计算的预付通行证。一次付款,不会自动续费。

查看通行证

继续阅读

VPN 安全

OpenVPN 的 TCP 与 UDP 有什么区别?

OpenVPN 可以通过 UDP 或 TCP 传输隧道数据。本文说明两者的区别、默认用 UDP 的原因、什么时候该用 TCP,以及怎样自己动手测试。

阅读约 9 分钟

VPN 基础

什么是 VPN 协议?

VPN 协议规定了你的设备与 VPN 服务器如何连接并保护流量。本文用通俗的语言讲清楚它的含义和主要取舍。

阅读约 9 分钟

故障排除

VPN 为什么很慢?如何让它变快

VPN 变慢时的实用排查清单:先测速,再排除自己网络的问题,然后逐步处理 Wi-Fi、后台应用、设备设置和视频卡顿。

阅读约 7 分钟

VPN 安全

VPN over TLS:工作原理与意义

用实用的角度走一遍 VPN over TLS:TLS 在隧道里做什么、验证什么、为什么常能通过防火墙,以及可能出什么问题。

阅读约 10 分钟

VPN 安全

WireGuard 与 OpenVPN 有什么区别

WireGuard 和 OpenVPN 都能建立加密隧道,但设计、复杂度和灵活性不同。本文用通俗的方式比较,并说明该怎样选择。

阅读约 9 分钟