Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 更改此协议以使用TCP流_C++_Tcp - Fatal编程技术网

C++ 更改此协议以使用TCP流

C++ 更改此协议以使用TCP流,c++,tcp,C++,Tcp,我为我的游戏制定了一个简单的协议: 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 f

我为我的游戏制定了一个简单的协议:

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
m_133s____11:Hello Worldi____-57989b0b1b0
然而,我不知道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和消息的开头,但我永远不会收到该消息,因为它不是消息

如何修改协议以解决这些潜在问题?正如我所预期的那样,只有收到格式正确的消息时,如果一个人的编码不好,把一切都搞乱了,那将是一场噩梦

谢谢


我决定在开头添加长度,并跟踪我是否正在处理邮件: 因此:

然后我有3种状态,读取以查找“p”,读取以查找“p”之后的长度,或者读取字节直到读取了长度字节

你觉得怎么样


它似乎工作得很好。

你现在做的是非常老式的磁带之类的东西。很好

您可能遇到的问题是,如果接收到消息的一部分,则无法判断您是否正在通过令牌

例如,如果您收到:

m12
i-12
这是信息12,还是信息122的第一部分

如果您收到:

m12
i-12
这是整数-12还是整数-124354的第一部分

因此,我认为您需要对其进行更改,使消息编号的宽度固定(例如四位数),字符串长度固定(例如6位数),整数宽度固定为10位数

你的例子是:

Message ID 133
String 'Hello World' length 11
int -57989
bool false
bool true
bool false
m_133s____11:Hello Worldi____-57989b0b1b0
这样,如果您得到消息的第一部分,您可以将其存储,并在处理它之前等待其余部分被接收

您也可以考虑使用控制字符来分隔消息部分。有一些ascii控制代码经常用于此目的,RS、FS、GS和US。所以一个信息可能是

[RS]FieldName[US]FieldValue[RS]fieldName[US]FieldValue[GS].
您知道什么时候有完整的消息,因为[GS]标志着结束。然后,您可以使用[RS]作为分隔符将其划分为多个字段,并使用[US]将每个字段划分为名称/值


有关简要信息,请参阅。

使用协议缓冲区。或者,在开始时对整个数据包的长度和可能的校验和进行编码。但实际上,使用PB或其他已建立的交换格式,没有必要重新发明轮子。我更喜欢使用我在这里所做的。如果你真的不想使用预定义的协议,考虑用STX/ETX包装整个包,我决定在开始时添加长度,并跟踪我是否正在处理消息:所以:P32 M133S11:Hello Word -57 989B0B1B0,然后我有3个状态,读取找到“p”,读取“p”之后的长度或读取字节,直到读取长度字节。你觉得怎么样?去吧。如果您得到的是非数字,则表示您已完成读取长度。