Apollo 技术文档Apollo 技术文档
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
指南
  • 架构概述
  • BigWorld 架构深度解析
  • BigWorld 进程架构与玩家生命周期
  • AOI九宫格系统详解
  • AOI广播与消息去重
  • Base 模块
  • Core 模块
  • Runtime 模块
  • Data 模块
  • Network 模块
  • /modules/actor.html
  • Game 模块
  • BigWorld 模块
服务器应用
API 参考
QA
GitHub
  • MMORPG 架构 QA

Q11: TCP vs UDP vs KCP,MMO 中各自的使用场景是什么?

核心结论

这不是一个“哪种协议更先进”的问题,而是一个“哪类消息该走哪种传输语义”的问题。

  • TCP 适合可靠性优先、顺序优先、实现成本敏感的消息
  • UDP 适合高频、可丢弃、最新状态覆盖旧状态的消息
  • KCP 适合想保留 UDP 低时延特征,同时在应用层补可靠性的场景

真正应该先做的,不是先选协议,而是先给消息分层:

  • 绝对不能丢的消息
  • 可以重试的消息
  • 可以丢旧保新的消息
  • 高频实时状态消息

一、不要先问“用什么协议”,要先问“消息是什么”

在 MMO 里,不同消息的要求差异非常大。

例如:

  • 登录请求不能随便丢
  • 背包修改不能乱序
  • 交易结果不能重复到账
  • 位置同步允许丢旧包
  • 语音消息允许轻微损伤

所以真正的判断顺序应该是:

  1. 这条消息是否必须可靠到达
  2. 这条消息是否必须按序处理
  3. 丢了以后是重试更合理,还是直接忽略更合理
  4. 它是状态消息,还是事件消息

如果这一步没分清,后面讨论 TCP、UDP、KCP 都容易变成空谈。


二、三种协议本质上在解决什么问题

2.1 TCP

TCP 提供的是:

  • 面向连接
  • 字节流
  • 可靠传输
  • 顺序到达
  • 拥塞控制
  • 流量控制

它最大的优点不是“快”,而是:

应用层不需要自己处理太多可靠性交付问题。

2.2 UDP

UDP 提供的是:

  • 无连接
  • 数据报
  • 尽力而为传输
  • 不保证到达
  • 不保证顺序
  • 不保证重传

它最大的优点不是“万能低延迟”,而是:

传输语义非常轻,应用层可以完全按自己的业务需求定制。

2.3 KCP

KCP 不是第四层新协议,而是:

  • 基于 UDP 承载
  • 在应用层实现可靠传输和重传策略
  • 目标是比 TCP 更积极地追求低延迟恢复

它的本质是:

你愿意多花一些带宽和实现复杂度,换取弱网下更好的交互时延表现。

这不等于它天然适合所有 MMO 消息。


三、真正该比较的不是“协议名”,而是传输语义

3.1 TCP 的优点和代价

优点:

  • 可靠
  • 有序
  • 通用
  • 网络设备兼容性最好
  • 开发和排查成本相对低

代价:

  • 有队头阻塞问题
  • 某个包卡住时,后续字节流也会被挡住
  • 对高频状态同步不友好
  • 如果你其实不需要可靠和严格有序,它会额外替你做很多没必要的事

3.2 UDP 的优点和代价

优点:

  • 开销低
  • 发送语义简单
  • 没有 TCP 那种字节流阻塞链路
  • 非常适合“最新状态覆盖旧状态”的消息

代价:

  • 可靠性全要自己做
  • 顺序控制全要自己做
  • 重传、拥塞、限速、反作弊都更麻烦
  • 一旦设计不好,很容易把问题从内核层搬到业务层

3.3 KCP 的优点和代价

优点:

  • 弱网下的恢复速度通常比 TCP 更激进
  • 对实时交互类消息更友好
  • 可以自己调窗口、刷新周期、重传策略

代价:

  • 带宽开销更高
  • 实现复杂度更高
  • 参数调不好反而会更差
  • 运维和排查复杂度高于纯 TCP

所以 KCP 的关键词不是“更强”,而是“更可调,也更容易用错”。


四、MMO 里真正应该怎么分消息

比起按系统名划分,更建议先按消息语义划分。

4.1 强可靠消息

特点:

  • 丢失不可接受
  • 重复执行风险高
  • 顺序通常重要

典型例子:

  • 登录认证
  • 角色创建
  • 背包修改
  • 道具发放
  • 交易
  • 支付结果
  • 邮件领取

这类消息优先考虑 TCP,或者至少要有和 TCP 等价的可靠交付语义。

4.2 可靠事件消息

特点:

  • 是离散事件
  • 通常不能直接丢
  • 但对绝对最低延迟也有一定要求

典型例子:

  • 技能释放请求
  • 技能命中确认
  • 战斗结算事件
  • 重要状态切换

这类消息有时适合:

  • TCP
  • 或 UDP + KCP / 应用层可靠事件通道

具体要看游戏节奏和弱网目标。

4.3 高频状态消息

特点:

  • 更新频率高
  • 旧消息很快失去价值
  • 更关心最新状态而不是每条状态都到达

典型例子:

  • 位置同步
  • 朝向同步
  • 动作状态广播
  • 短周期 AOI 状态

这类消息天然更适合 UDP 语义,而不是强行逐条可靠送达。

4.4 媒体流或弱可靠消息

典型例子:

  • 语音
  • 部分观战流
  • 某些低价值表现层事件

这类消息允许部分损失,重点是时效性。


五、为什么很多 MMO 主体仍然偏向 TCP

很多人一提游戏网络就默认“实时游戏一定 UDP/KCP”,这对 MMO 并不总是成立。

原因很简单:

  • MMO 主体业务里可靠消息很多
  • 很多系统是状态管理,不是纯操作流
  • 游戏节奏通常不像 FPS 那样极度依赖毫秒级输入反馈
  • 实现复杂度和运维成本在 MMO 里非常重要

所以对大量 MMO 项目来说:

  • 登录
  • 背包
  • 交易
  • 社交
  • 大部分任务与成长系统

这些核心链路用 TCP 是完全合理的。

甚至有些 MMO 会选择“整体 TCP + 客户端插值补偿”,而不是一开始就上复杂的混合协议栈。


六、什么时候 UDP / KCP 真正有价值

6.1 UDP 更有价值的场景

  • 高频位置同步
  • 高频姿态同步
  • 语音
  • 允许丢旧保新的状态流

这里的核心不是“更快”,而是:

你根本不想为旧状态做可靠重传。

6.2 KCP 更有价值的场景

  • 技能释放和战斗操作对时延敏感
  • 弱网质量波动明显
  • 希望比 TCP 更快恢复丢包
  • 团队有能力维护和调优额外传输层

如果团队没有能力长期维护这套复杂度,KCP 的收益未必比它的成本更高。


七、几个常见误区

7.1 误区一:UDP 一定更适合游戏

不对。

UDP 只意味着:

  • 你拿到了更原始的传输语义
  • 但可靠性、顺序、限流、拥塞都要自己补

如果你的消息大部分本来就必须可靠,那 UDP 未必更合适。

7.2 误区二:KCP 一定比 TCP 好

不对。

KCP 只是在某些弱网、实时交互场景下,可能比 TCP 更符合目标。

但它带来的额外问题包括:

  • 更多带宽
  • 更多参数
  • 更复杂的排查
  • 更高的客户端和服务端维护成本

7.3 误区三:一个项目只能选一种协议

也不对。

更成熟的做法往往是按消息类型混合选择语义,甚至即使外部只暴露一种物理连接,内部也会做多通道消息分级。


八、一个更实用的选择方法

8.1 如果你优先要稳定和落地

优先考虑:

  • 主链路 TCP
  • 通过消息分级、客户端插值、预测和压缩优化体验

这通常是中小团队最稳的路线。

8.2 如果你已经明确有高频实时瓶颈

再考虑:

  • 把高频状态流单独拆到 UDP
  • 或者把实时战斗消息放到 KCP / 应用层可靠 UDP 通道

这时要先证明:

  • 问题真的是 TCP 传输语义导致
  • 而不是序列化、广播、AOI、主线程处理或客户端表现层问题

8.3 一个典型的现实组合

比较常见的思路是:

  • TCP 负责登录、背包、社交、任务、资产
  • UDP 或 KCP 负责位置、动作、实时战斗状态

但是否要走到这一步,要看项目类型和团队能力,不是默认答案。


九、总结

TCP、UDP、KCP 的选择,本质上不是协议偏好,而是消息语义选择。

对 MMO 来说:

  • 强可靠、强一致消息优先 TCP
  • 高频状态同步更适合 UDP 语义
  • 对低时延可靠交互有明显需求时,再考虑 KCP

如果还没有先把消息分层,只讨论“项目该用 TCP 还是 UDP/KCP”,结论通常都不够稳。


参考资料

  • KBEngine GitHub - Network
  • KCP
  • TCP
  • UDP
在 GitHub 上编辑此页
最后更新: 3/20/26, 6:06 AM
贡献者: cuihairu