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

系统1:ThinkPad T570、Windows10、QT5.12.2(Qt Creater 4.8.2)
在与其他设备进行UDP通信时,我一般会定义通信协议包结构,如下图所示是一个简单的例子:
QT进行通信,定义结构体时需要字节对齐的问题_第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低位在前,高位在后
};			

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

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)//恢复对齐状态

你可能感兴趣的:(QT)