文字游戏的长连接:Telnet 选项协商与状态同步浅析

MUD 客户端与服务器之间默认走 Telnet 协议,底层是一条 TCP 长连接,一个连接对应一个玩家会话。理解这条连接上发生了什么,是排查「玩家掉线」「画面乱码」类问题的基础。

IAC 选项协商

连接建立后,双方会通过 IAC 报文交换 DO / WILL / DONT / WONT,协商各自支持的能力。实践中常见的有几类:

TCP 是字节流,必须自行按行切分

客户端一次发来的数据不一定是一条完整命令,也可能几条挤在一个包里。服务端的标准做法是维护输入缓冲,遇到换行符才切出一条命令交给命令解析器。

// 简化的按行切分逻辑
void net_read(string data) {
    input_buffer += data;
    while (strsrch(input_buffer, "\n") != -1) {
        string line = input_buffer[0..strsrch(input_buffer, "\n") - 1];
        input_buffer = input_buffer[strsrch(input_buffer, "\n") + 1..];
        process_command(trim(line));
    }
}

状态同步靠事件广播

文字游戏没有帧同步的概念,世界的一切变化都以事件广播体现:移动、look、战斗消息、环境描述。工程上要控制两件事——广播范围(同房间 / 同区域 / 全服)和广播频率。全服广播必须限流,否则一条世界公告就能把所有人踢下线。

断线与重连

为每个连接设置心跳超时,超时未收到数据的连接主动关闭。玩家断线后不要立即销毁角色对象,保留一段 linkdeath 时间,重连时恢复原会话——这对文字游戏的体验至关重要。

输入安全

对单条命令长度、频率做限制;GMCP 等子协议数据同样需要校验,构造异常报文可能影响驱动稳定性,这类攻击在公网 MUD 上真实存在。

← 上一篇:任务系统设计 返回文章列表