我正在设计一个专用网络协议。我需要选择一个字符串分隔符。
如果分隔符为string01\0string02\0string03\0
\0
字符串不仅是ascii,它是任何最终用户定义的编码字符串,如utf8或base64编码的二进制数据。
我的目的是制作灵活的小型协议,因此字符串应该支持某种压缩算法。我想知道分隔符对此是否重要。
答案 0 :(得分:1)
如果编码是最终用户定义的,它可能包含\0
字节,例如UTF-16,因此运行长度编码的字符串可能效果最好:
\x08string01\x08string02\x08string03
或者,如果您需要长度超过255个字节的字符串,请选择2字节(最大65535)或更大的big-endian(网络协议约定)值:
\x00\x08string01\x00\x08string02 (ASCII)
\x00\x10\x00s\x00t\x00r\x00i\x00n\x00g\x000\x001 (UTF-16BE)
答案 1 :(得分:0)
除了已由Mark提出的长度编码外,您还可以使用转义字符。你设置了一个分隔符(比如说\ 0),如果数据中出现\ 0,你就会设置一个特殊的"转义字符"在它之前,要逃避它的特殊含义。一些协议使用它,例如HDLC:
......他们使用"控制八位字节透明度",也称为"字节填充"要么 " octet stuffing"。帧边界八位字节是01111110,(7E in 十六进制表示法)。 A"控制转义八位字节",具有位序列 ' 01111101',(7D十六进制)。如果出现这两个八位字节中的任何一个 传输的数据,一个转义八位字节被发送,然后是 原始数据八位位组,位5反转。例如,数据 序列" 01111110" (7E十六进制)将作为" 01111101发送 01011110" (" 7D 5E" hex)
答案 2 :(得分:0)
如果我是你,我将采用协议版本的字符串格式(即ASCII或UTF8或其他)。版本协议我认为你应该参与协议握手(初始化)。例如:
1. Client opens TCP connection to Server
2. Server> \x... <-- magic
3. Server> \x01 <-- Protocol version
4. Client> \x00 <-- Ok
然后使用字符串终止字符串使用数据大小标头之前的字符串发送,如:
Client or Server> 0x000f <-- following data will be 100 bytes
Client or Server> .... // 100 of raw data is being transmitted and then decoded using the right encoding that is protocol coupled.
我认为通过这种方式,协议更容易理解,更容易扩展。