【发布时间】:2012-05-25 06:55:49
【问题描述】:
我为我的游戏制定了一个简单的协议:
b = bool
i = int
sINT: = string whose length is INT followed by a : then the string
m = int message id.
例子:
m133s11:Hello Worldi-57989b0b1b0
这将是:
Message ID 133
String 'Hello World' length 11
int -57989
bool false
bool true
bool false
但是我不知道 TCP 可能只发送消息的一部分。我不确定如何修改它以便我可以执行以下操作:
on receive data from client:
use client's chunk parser
process data
if has partial message then try to find matching END
if no partial messages then try to read a whole message
for each complete message in queue, dispatch it
我可以通过在消息的开头添加 B 并在末尾添加 E 来做到这一点,然后解析第一个字符为 B,最后一个字符为 E。
唯一的问题是如果 我在中间收到了一些不符合协议的愚蠢的东西。或者,如果我应该只收到不是消息而只是字符串的东西怎么办。因此,如果我打算以某种方式接收字符串 HelloB,那么我会将其解析为 hello 和消息的开头,但我永远不会收到该消息,因为它不是消息。
如何修改协议以解决这些潜在问题?尽管我预计只会收到格式正确的消息,但如果一个消息编码不良并且一切都乱七八糟,那将是一场噩梦。
谢谢
我决定在开头添加长度并跟踪我是否正在处理消息: 所以:
p32m133s11:Hello Worldi-57989b0b1b0
然后我有 3 种状态,读取以查找 'p',读取以查找 'p' 之后的长度或读取字节直到读取长度字节。
你怎么看?
看起来效果不错。
【问题讨论】:
-
使用协议缓冲区。或者,在开始时对整个数据包的长度和可能的校验和进行编码。但实际上,使用 PB 或其他已建立的交换格式,没有必要重新发明轮子。
-
我更喜欢使用我在这里制作的东西。
-
如果您真的不想使用预定义的协议,请考虑使用 STX/ETX en.wikipedia.org/wiki/C0_and_C1_control_codes 包装整个数据包