05-UDP服务器与可靠性
UDP 服务器与可靠性——无连接传输下如何自建可靠
网络系统主线(01)走的是 TCP:连接建立 → 连续字节流 → Connection 管理。但很多实时场景(游戏、语音、嵌入式)用的是 UDP——无连接、以 Datagram(数据报)为单位。这一条线回答:① TCP 与 UDP 最核心的区别(生命周期与运行流两视角);② UDP 服务器怎么自建(socket → recvfrom → decode → dispatch → service → sendto);③ UDP 不代表没有客户端状态——Connection State / Session / Token 三分(详见 04-系统角色/09);④ 可靠性必须自己构建(Sequence / ACK / 重传)。
一、TCP 与 UDP 最核心的区别
1 | TCP:连接建立(客户端→服务器→Connection)→ 连续字节流(可靠、有序) |
Qt 中:TCP → QTcpServer + QTcpSocket,UDP → QUdpSocket。
UDP 自定义协议服务器
1 | Qt(QUdpSocket → Datagram) |
例如游戏 MOVE:
1 | 玩家 → UDP Datagram → MOVE → Decoder → MoveMessage → Dispatcher → MoveHandler → GameService.move() |
与 TCP 版本最大的区别:TCP 通常需要处理连续字节流和连接状态(Buffer 暂存);UDP 天然以 Datagram 为单位。
UDP 不代表没有「客户端状态」
UDP 没有 TCP connection,但应用程序仍然可以维护客户端状态:
1 | ClientEndpoint |
TCP Connection 是传输层提供的连接语义;UDP Server 可以自己建立「客户端状态」。
UDP 适合什么
实时游戏数据(某个 MOVE 丢了直接 100 → 102,不需要重传);购买物品、扣钱、登录、保存角色等需要可靠传输语义的,用 TCP / 可靠 UDP / 自定义确认重传。
TCP/UDP 不改变你的业务分层:统一模型仍是
Network → Protocol → Decoder → Message → Dispatcher → Handler → Service,只是传输方式不同。
二、自写 UDP 服务器(系统 Socket API)
最底层
1 | int fd = socket(AF_INET, SOCK_DGRAM, 0); |
没有 listen() / accept(),因为 UDP 没有连接建立过程。发送用 sendto()。
收到一个 UDP 包
1 | recvfrom() → Datagram → Decoder → MoveMessage → Dispatcher → MoveHandler → GameService.move() |
真正麻烦的东西:可靠性
UDP 只保证「把一个 Datagram 发给另一个 Endpoint」,不保证可靠/有序/不重复/不丢失/不乱序。如果业务需要,必须自己构建:
1 | UDP Server |
例如客户端发送 #100、#101 丢失、#102:服务器发现 #101 缺失 → 要求重传 → 客户端重发 #101——这时实际上开始构建自己的可靠传输协议。
游戏服务器的 Connection
UDP 下 Connection 不能理解成 TCP Connection,而是自行定义的应用层客户端状态:
1 | struct ClientSession { |
自写 UDP 服务器的完整认识
1 | 系统 Socket → UDP → Datagram → 自定义协议 → Decoder → Dispatcher → Handler → Service → 业务 |
如果业务需要可靠性,在 UDP 和业务之间增加可靠传输机制;需要高并发,增加 EventLoop/IOCP/epoll/io_uring/多线程;需要加密,增加 Encryption/Authentication。
最小版本就是
socket → recvfrom → decode → dispatch → service → sendto,随着需求增加,再逐步增加并发、状态、可靠性、加密等服务器能力。
三、Connection State / Session / Token 三分(速览)
UDP 服务器把「连接、会话、凭证」三个概念分得很清楚——它们不是一回事:
1 | Connection State(网络层/服务器运行时): |
1 | IP:Port → Client State → Player → Session → Token/Authentication → GameService |
完整展开见 04-系统角色/09-认证与请求上下文.md——Token/Session 属于业务/应用层,不属于 TCP/UDP 的连接状态;不要把 token 塞进 connection/。
四、这一条线的位置
1 | 网络系统(线组): |
本线与 01 的关系:01 走 TCP 主线(连接建立 → 字节流 → Connection 管理);本线是 UDP 支线(无连接 → Datagram → Client State)。两条线的业务分层完全一致(Network → Protocol → Decoder → Message → Dispatcher → Handler → Service),只是传输语义不同。TCP 的 Connection 由传输层提供;UDP 的 Connection 必须应用层自建(Client State + 可靠性机制)。
收束
1 | TCP vs UDP 最核心的区别: |
UDP 服务器与可靠性 = 无连接传输下的服务器构建:socket → recvfrom → decode → dispatch → service → sendto 是最小闭环,可靠性(Sequence/ACK/重传)、并发、状态、加密随需求逐步增加。 TCP/UDP 不改变业务分层,只是传输方式不同。
