Skip to content

引言

网络通信是游戏开发中绕不开的话题,TCP 和 UDP 的选择是网络层设计的第一道选择题。这篇文章整理两者的核心差异、各自在游戏中的典型应用场景,以及实际项目中常见的组合方案。

一、TCP vs UDP 核心差异

TCPUDP
连接模型面向连接(三次握手)无连接
可靠性保证送达、有序、不重复不保证送达、不保证顺序、可能重复
流量控制滑动窗口、拥塞控制
数据边界字节流(需自行分包)保留报文边界
头部开销20 字节8 字节
适用场景文件传输、HTTP、登陆认证实时游戏、音视频通话

这些是教科书级别的结论,但在游戏开发中,真正影响选择的不是这些表层的差异,而是下面几个实际工程问题。

二、游戏为什么偏爱 UDP

1. 过时数据的价值为零

游戏中最核心的数据类型是状态快照——角色位置、朝向、动作状态。这类数据有极强的时效性:上 100ms 的位置信息对当前帧的渲染和逻辑已经没有意义了。TCP 的可靠重传机制在这种情况下是负资产——如果一个位置包丢了,TCP 会阻塞后续数据直到重传成功,导致玩家看到的画面"卡住",而不是平滑过渡到最新状态。

UDP 的思路是:丢了就丢了,发下一个。接收端总是处理最新到达的包,用插值和预测来平滑中间的状态变化。

2. 自定义可靠性

游戏通常不需要"全都可靠",只需要"关键信息可靠"。UDP 给了你最大自由度——你可以在应用层对不同类型的消息做不同策略:

  • 移动位置:允许偶尔丢失(快发多次,丢一个不影响)
  • 技能释放指令:必须可靠(应用层 ACK + 超时重传)
  • 聊天消息:必须可靠、必须有序(应用层做序列号 + 排序)

这种按需可靠比 TCP 的全局可靠高效得多——不需要为 90% 可以丢的数据付出 100% 可靠的代价。

3. 避免 TCP 队头阻塞(Head-of-Line Blocking)

TCP 保证字节流的严格有序性。如果包 #5 丢了,即使包 #6-#10 已经到了,应用层也读不到它们——内核会一直等 #5 重传成功。在 30ms 延迟的网络上,一次丢包可能造成 200ms+ 的卡顿。对于 FPS/MOBA 这类对延迟敏感的游戏,不可接受。

三、但 TCP 在游戏中并非无用

1. MMO 大世界

MMO 的战斗通常不走实时操作,而是指令下发 + 服务器确认的模式(客户端发送指令 → 服务器收集计算 → 广播状态)。这种模式下延迟容忍度相对较高(战斗逻辑帧率 5-20),而且 MMO 对"数据不丢"的要求比"延迟极低"更重——你不想玩家的交易、背包操作、任务状态因为丢包而出现不一致。

很多 MMO 使用 TCP 作为底层传输,客户端预测和插值在应用层做延迟平滑。

2. 回合制和战棋

《归义军传说》这种回合制 SRPG 对延迟完全不敏感——玩家做出操作后等 0.5 秒还是 0.2 秒看到结果,体验没有实质区别。TCP 的有序可靠特性恰好完美匹配这种场景。协议层面可以直接用可靠传输,省去应用层重传逻辑。

3. 登陆/支付/更新

任何时候涉及账号认证、充值扣费、资源下载,都必须是 TCP(或更上层的 HTTP/TLS)。这些场景数据完整性是第一位的,延迟多几百毫秒完全可接受。

四、常见组合方案

现实中大多数商业游戏不是"TCP 还是 UDP",而是"TCP 和 UDP 怎么配合":

  1. TCP 做大厅 + UDP 做战斗:大厅(匹配、聊天、商城)用 TCP,进入战斗切 UDP。这是 FPS/MOBA 的标准做法。

  2. 纯 TCP + 应用层优化:部分 MMO 和移动端游戏因为穿透 NAT/防火墙的复杂性,全部走 TCP,但在应用层做逻辑层分包(模仿 UDP 的消息边界)、时序无关的状态处理(类似 UDP 的"只关心最新值")。

  3. RUDP / KCP / ENET 等中间方案:在 UDP 之上实现可靠层。KCP 是一个常见选择——牺牲部分带宽换取比 TCP 更低的延迟(更激进的超时重传、选择性 ACK)。适合延迟敏感但又需要一定可靠性保证的场景。

  4. WebSocket:H5 游戏和部分独立游戏的轻量选择。底层是 TCP,但提供了消息边界(帧协议封包),省去了 TCP 字节流的拆包逻辑。适合对延迟要求不高的网页游戏和回合制。

五、项目中实际遇到过的问题

在 MMO 项目的实际开发中,真正花费精力的往往不是 TCP vs UDP 的选择,而是上层同步策略的设计:

  • 客户端预测的乐观执行和服务器确认冲突时怎么回滚(最常见的是"我以为我移动到了这里,但服务器说不对")
  • 技能前摇时间的调整(必须在服务器的逻辑帧时间 + 网络往返延迟内完成,前摇太短会让玩家觉得"技能经常被打断")
  • 移动平滑策略的选择(直接设置位置 vs 线性插值 vs 曲线插值,不同游戏体量不同)

这些问题在传输层选型确定之后才会暴露,但它们往往比"用 TCP 还是 UDP"更影响最终手感。

参考文献