通信协议的设计
常用的某协议设计如下: 包括帧头,命令字,帧序号,帧长度,帧数据,校验字,帧尾。
1B |
1B |
2B |
4B |
NB |
2B |
2B |
帧头 |
命令字 |
帧序号 |
帧长度 |
帧数据 |
校验字 |
帧尾 |
HEAD |
CMD |
FRAME_SEQ |
DATA_LEN |
DATA |
CRC |
TAIL |
一般协议解析时,定位到帧头,通过帧长度汲取一个帧。然后校验下校验字和帧尾确保本帧没问题。
然后这样设计有一个小风险,就是帧数据也包含帧头就很尴尬。
1、读取到错误的帧长度有内存溢出风险。
2、读取到错误的帧长度导致后续的帧都被误读取。
3、本帧必然发生校验字错误被丢弃。
因此,最好能对帧数据进行帧头的剔除工作。
今天翻看tcp/ip看到一节,SLIP的协议包装可以借鉴下。
如图,每段IP数据段被封装时,有个END标记“0xC0“,对数据报中的“0xC0”进行加工,翻译成“0xdb0xdc”,再对报文中的"0xdb"后面加上“0xdd”。
这样只有在数据包的首尾才有“0xC0”了。
缺点就是1、报文稍稍变长几个字节,稍微影响点带宽(取决于保卫中关键字的出现频率)
2、需要对数据报进行逆向翻译操作,带来了一定的工作量。
但总体而言还是有意义的吧,总比报文乱序了好。