《游戏服务端编程实践》3.1.1 TCP / UDP / WebSocket 对比

对比分析 TCP、UDP、WebSocket 这三种常用的游戏通信协议,包括它们的定位、价值、架构与使用场景。同时,介绍 TCP 的可靠传输、UDP 的低延迟、WebSocket 的双向通信等特性,展示如何根据游戏需求选择合适的协议。

一、引言:游戏通信的本质是“实时性 + 一致性”的平衡

在游戏开发中,通信协议决定了“游戏世界如何同步”。
它不仅仅是“传输数据”,而是塑造了整个游戏架构的形态

不同类型的游戏对“实时性、可靠性、带宽、顺序性”的要求差异极大:

游戏类型实时性容忍丢包数据顺序要求典型协议
SLG / RPG低(秒级)不容忍必须按序TCP / WebSocket
MOBA / FPS高(毫秒级)可容忍局部无序可接受UDP / QUIC
休闲社交类不容忍强一致WebSocket
直播 / 弹幕 / 聊天中高可容忍不重要UDP / WebSocket

因此,理解 TCP、UDP 与 WebSocket 的机制与差异,是构建高效游戏网络层的前提。


二、TCP:面向连接的可靠传输协议

2.1 核心特征

TCP(Transmission Control Protocol)是一个面向连接可靠的字节流协议
由操作系统的内核 TCP 栈负责维护。

特性描述
连接导向(Connection-oriented)三次握手建立连接,四次挥手关闭
可靠传输(Reliable Delivery)通过确认(ACK)与重传机制确保数据到达
有序性(In-order Delivery)数据按序排列,不会乱序
流量控制(Flow Control)避免发送方淹没接收方
拥塞控制(Congestion Control)根据网络情况动态调整速率

TCP 就像“顺序送快递”:即使中途延误,也保证包裹按顺序抵达。


2.2 TCP 的连接建立(3-way handshake)

sequenceDiagram
Client->>Server: SYN (同步请求)
Server-->>Client: SYN + ACK (确认连接)
Client->>Server: ACK (确认)
Note right of Server: 连接建立

2.3 可靠传输机制

TCP 使用序列号 + 确认号机制:

  • 每个包带序列号(seq);
  • 接收方返回 ACK;
  • 丢失包将触发重传;
  • 超时自动调整窗口大小。

TCP 在可靠性和顺序性上非常强,但代价是延迟增加

2.4 在游戏中的适用场景

适合场景示例
RPG / SLG / MMO登录、战斗结果、任务状态
策略与模拟类行为决策、回合确认
商城 / 聊天 / 经济系统防丢消息、强一致性需求

2.5 TCP 的局限

问题描述对游戏的影响
延迟积累(Head-of-line blocking)丢一个包会阻塞后续所有包玩家感觉卡顿
系统调用频繁每次收发都需进入内核CPU 开销大
粘包 / 拆包问题连续发送数据会被合并需应用层封包
重传延迟网络抖动会造成重传等待影响实时性

2.6 TCP 粘包 / 拆包处理示例(Java)

ByteBuffer buffer = ByteBuffer.allocate(1024);
int length = inputStream.read(buffer.array());
if (length > 0) {
    while (buffer.remaining() >= HEADER_SIZE) {
        int msgLen = buffer.getInt();
        if (buffer.remaining() < msgLen) break;
        byte[] msg = new byte[msgLen];
        buffer.get(msg);
        handleMessage(msg);
    }
}

三、UDP:无连接的高性能传输协议

3.1 核心特征

UDP(User Datagram Protocol)是一个无连接不可靠不保证顺序的协议。
它直接将数据包(Datagram)发到目标地址,不建立连接,不确认,不重传。

特性描述
无连接(Connectionless)不建立握手,直接发包
不可靠(Unreliable)丢包不重传
无顺序保证(Out-of-order possible)包可能乱序到达
低延迟(Low Latency)减少握手与确认
轻量级头部仅 8 字节

UDP 就像“广播喊话”:说出去就算,听到与否由对方决定。

3.2 在游戏中的应用场景

类型示例
FPS / 射击类玩家移动、射击方向、帧同步
MOBA技能释放、坐标同步
实时对战房间广播、Tick 推进
实时媒体语音、弹幕、直播流

对这些游戏来说,“宁可丢包,也不能卡顿” 是首要原则。

3.3 UDP 优势与劣势

优势劣势
✅ 延迟低❌ 不可靠
✅ 开销小❌ 乱序可能
✅ 不阻塞❌ 无拥塞控制
✅ 适合实时❌ 自行处理重传与校验

UDP 不会帮你“兜底”,你得自己实现可靠层。

3.4 游戏常用可靠 UDP 封装(RUDP)

许多游戏框架会在 UDP 之上自建“可靠层”,例如:

  • ACK 序列确认;
  • 丢包重发;
  • 滑动窗口;
  • 包序号与校验。

Go 示例:

type Packet struct {
    Seq  uint32
    Ack  uint32
    Data []byte
}

func SendReliable(conn *net.UDPConn, pkt Packet) {
    buf := Encode(pkt)
    conn.Write(buf)
    WaitAck(pkt.Seq)
}

RUDP(Reliable UDP) 是许多实时游戏的底层基础,例如 Quake、Overwatch、CSGO 都使用自研 UDP 可靠协议。

四、WebSocket:基于 TCP 的全双工通信协议

4.1 核心特征

WebSocket 是建立在 TCP 之上的“全双工通信协议”,
它使浏览器或客户端能够与服务器持续保持连接,支持双向实时数据传输。

特性描述
基于 TCP使用同样的可靠传输机制
全双工(Full-duplex)客户端和服务端可同时发送
长连接一次握手,多次通信
跨平台 / 跨语言浏览器、Unity、手机端皆可使用
适合低频实时通信聊天、匹配、通知等

WebSocket 是 Web 时代的“游戏 TCP 长连接方案”。

4.2 握手过程(Upgrade from HTTP)

sequenceDiagram
Client->>Server: HTTP GET /chat  (Upgrade: websocket)
Server-->>Client: 101 Switching Protocols
Note right of Server: 通信协议升级完成
Client->>Server: send("hello")
Server-->>Client: send("world")

它通过 HTTP 升级握手,建立后长期保持 TCP 通道。

4.3 在游戏中的典型应用

模块功能特点
登录 / 匹配 / 聊天实时通信、通知数据小,交互频繁
休闲类 H5 游戏状态同步浏览器原生支持
轻量回合制游戏指令传递对延迟容忍
跨端心跳 / 热更通道通用数据推送管理与监控层常用

4.4 WebSocket 的实现成本与限制

优点缺点
✅ 开发友好(内建于浏览器)❌ 基于 TCP,延迟相对高
✅ 双向通信❌ 需要心跳维持
✅ 安全(TLS 支持)❌ 性能弱于原生 TCP
✅ 与 HTTP 共存❌ 不适合高频帧同步

因此,WebSocket 适合逻辑层通信,而不是实时战斗层。

五、三种协议的系统对比

特征TCPUDPWebSocket
连接类型面向连接无连接长连接(基于TCP)
可靠性✅ 高❌ 无✅ 高
顺序性✅ 保证❌ 不保证✅ 保证
延迟中高
丢包处理自动重传需自实现自动重传
带宽占用
适用场景MMO、SLGFPS、MOBAH5、聊天、社交
应用层封包需要自定义框架内封装
浏览器支持✅ 是
常见库Netty, MinaENet, KCPSocket.IO, ws
性能调优TCP_NODELAY、NagleBuffer/RTT心跳间隔、压缩

六、实际项目中的混合架构模式

在现代游戏项目中,通常不会单独使用一种协议,而是组合多种通信层:

graph TD
A["客户端"] --> B["TCP (登录/数据)"]
A --> C["UDP (战斗/同步)"]
A --> D["WebSocket (聊天/通知)"]
协议负责内容
TCP登录、验证、经济系统
UDP战斗逻辑、帧同步
WebSocket聊天、匹配、监控

例如:

  • 登录 → TCP;
  • 战斗 → UDP;
  • 断线重连 / 消息通知 → WebSocket;
  • GM 管理 / 分析 → HTTP + WebSocket。

七、Java 实践:混合协议网关架构

public class GameGateway {
    private final TcpServer tcp;
    private final UdpServer udp;
    private final WebSocketServer ws;

    public GameGateway() {
        tcp = new TcpServer(8080);
        udp = new UdpServer(8081);
        ws  = new WebSocketServer(8082);
    }

    public void start() {
        tcp.start();
        udp.start();
        ws.start();
    }
}
  • 逻辑服可以通过 统一消息总线(Message Bus) 路由不同协议的输入;
  • 各模块独立维护连接;
  • 支持多协议并行处理。

八、Go 实践:统一协议抽象接口

type Conn interface {
    Send(data []byte) error
    Recv() ([]byte, error)
    Close() error
}

func HandleConnection(c Conn) {
    for {
        msg, err := c.Recv()
        if err != nil {
            break
        }
        process(msg)
    }
}

通过统一接口封装 TCP / UDP / WebSocket,
上层逻辑可透明使用同一套通信抽象。

九、协议选型建议

游戏类型推荐协议理由
MMORPG / SLGTCP / WebSocket强一致、顺序敏感
FPS / 动作类UDP + 自定义可靠层低延迟关键
MOBA / 实时竞技UDP + 帧同步稳定流畅
休闲 / 卡牌WebSocket / TCP逻辑简单、易部署
H5 / 小程序游戏WebSocket浏览器友好、无插件
跨端系统模块HTTP + WS管理、匹配、聊天

十、总结与设计启示

网络协议不是“选择一种”,而是“根据游戏特性设计一套组合策略”。

  1. TCP = 稳定性
    → 适合登录、任务、经济等不容错逻辑。
  2. UDP = 实时性
    → 适合战斗同步、动作游戏。
  3. WebSocket = 兼容性
    → 适合 H5、跨平台、低频通信。
  4. 混合方案 = 工业标准
    → 多协议并行,统一路由与序列化层。

在高并发分布式架构下,真正的“协议选型能力”是一种系统设计思维:
你选择的不是传输方式,而是体验与公平的平衡点。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页