QT进行通信,定义结构体时需要字节对齐的问题

系统1:ThinkPad T570、Windows10、QT5.12.2(Qt Creater 4.8.2)
在与其他设备进行UDP通信时,我一般会定义通信协议包结构,如下图所示是一个简单的例子:
在这里插入图片描述
,然后在程序中我会定义一个结构体,如下所示:

struct PACKET_PC1_PC2
{
    quint32             m_nFrameHead;//0xFFAA低位在前,高位在后
    quint32             m_nUtcTime[2];//时戳,UTC相对时间,以秒为单位,以1970年1月1日0时0分0秒为基准。第一个字段表示整秒数,第二个字段表示为毫秒数
    qint16              m_nDataTypeID;//0:默认值    1:config文件数据    2:ini文件数据    3:csv数据
    quint32             m_nPacketID;//发送的包序号
    char                m_cReserved[490];
    quint32             m_nFrameEnd;//0xFFFF低位在前,高位在后
};			

然后定义一个结构体对象,并对其赋值

PACKET_PC1_PC2 packetPc1_Pc2;
//...... 对packetPc1_Pc2进行赋值

然后将packetPc1_Pc2通过socket发送出去

QByteArray baData;
baData.resize(sizeof(PACKET_PC1_PC2));
char* ptr_ctemp = baData.data();
memcpy(ptr_ctemp,&packetPc1_Pc2,sizeof(PACKET_PC1_PC2));
qint64 nSendLen = m_SocketSendCSV->writeDatagram(baData,QHostAddress(m_strRemoteIP),m_nRemotePort);

接下来问题来了,对方收到包发现变量m_nPpakcetID的值死活都不对,然后我用wireshark抓包,研究了半天才发现抓到的包里面的变量m_nDataTypeID和变量m_nPpakcetID所在的字节之间多了2个字节,且多出来的2个字节的值都为0,然后我就断定肯定是字节对齐的问题!系统默认是4字节对齐的,就是说变量m_nDataTypeID占用内存由2个字节编程了4个字节
每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。
n 字节的对齐方式对结构的存储的特殊处理确实提高 CPU 存储变量的速度,但是有时候也带来 了一些麻烦,就像我上面描述的问题那样。
解决方法:
在结构体前后加上如下代码进行字节对齐:

 #pragma pack(push) //保存对齐状态
 #pragma pack(1)//设定为1字节对齐
 struct PACKET_PC1_PC2
    {
        quint32             m_nFrameHead;//0xFFAA低位在前,高位在后
        quint32             m_nUtcTime[2];//时戳,UTC相对时间,以秒为单位,以1970年1月1日0时0分0秒为基准。第一个字段表示整秒数,第二个字段表示为毫秒数
        qint16              m_nDataTypeID;//0:默认值    1:config文件数据    2:ini文件数据    3:csv数据
        quint32             m_nPacketID;//发送的包序号
        char                m_cReserved[490];
        quint32             m_nFrameEnd;//0xFFFF低位在前,高位在后
    };			
#pragma pack(pop)//恢复对齐状态
  • 9
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GreenHandBruce

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值