最近在搞个网络通信协议,
采用socket udp传输,
运行时,居然报段错误了,
经过debug,发现居然是因为字节对齐问题导致的。
这个问题在实现通信协议,是经常会遇到的问题,
为了方便读者理解,
我把内容做了简化,分享给大家。
1、协议说明
通信协议信令格式如下:
根据协议格式,我造了一个数据frm,代表我收到的某个信令,
根据协议,
信令的字段与原始帧对应关系如下
于是我实现了一个简单的解析代码【该代码有问题】
编译运行后,其中len的值居然是0107,而不是0007
这其实就是因为编译器采用了字节对齐导致的,
在给pmsg->len赋值时,因为需要2个字节,
这两个字节是frm[3]、frm[4]这正好分布在两个字里,
编译器忽略了frm[3],最终将frm[4]、frm[5]合在一起赋值给了pmsg->len
为什么有字节对齐?
简单的说内存对齐能够提高 cpu 读取数据的速度,减少 cpu 访问数据的出错性(有些 cpu 必须内存对齐,否则指针访问会出错)。
原因找打了,下面就是解决了。
2、解决办法
1. 方法1 #pragma pack()
该预处理指令用来改变对齐参数。在缺省情况下,C编译器为每一个变量或数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对齐参数:
完整代码
2. 方法2
老老实实将收到的数据帧逐字节解析,
并填充到struct protocol_msg_s
end