后面打算写Qt关于网络编程的博客,网络编程就绕不开字节流数据传输,字节流数据的传输一般是根据协议来定义对应的报文该如何组包,那这就必然牵扯到了大端字节序和小端字节序的问题了。不清楚的大小端的可以看一下相关资料:大小端模式_百度百科 (baidu.com)。
这里看一个具体的例子比如某个报文协议是这样定的:
报头 | ... |
设备编号 | U16(两个字节) |
设备温度 | U16(两个字节) |
设备湿度 | U16(两个字节) |
设备状态 | U16(两个字节) |
报尾 | ... |
那么传输过程的报文结构,除去头尾之外应该是这样的:
代码报文结构体这样定义
struct DeviceData {
quint16 number;
quint16 temperature;
quint16 humidness;
quint16 status;
};
然后简单测试一下
QByteArray data;
DeviceData d;
d.number = 0x1234;
d.temperature = 0x5678;
d.humidness = 0x4321;
d.status = 0x8756;
data.append(reinterpret_cast<char *>(&d), sizeof(DeviceData));
qDebug() << data.toHex();
编译运行查看一下打印结果:
如果看了前面关于大小端的资料应该就会明白为什么这里打印结果是“3412785621435687”,这里也有一个参考的文章:大小端格式由编译器,操作系统还是CPU决定的?答案是CPU_大端cpu采用小端编译链-CSDN博客我的机器cpu,如果不采取任何处理,这里输出的确实是小端数据,如果是大端那么就会输出对应的“1234567843218756”。如果上文中举例的协议定的就是小端数据传输那么就是这样写,无需做任何处理。如果是大端数据传输则需要做对应的处理。同样上文中还存在一个问题,比如设备编号协议里面定的是无符号一个字节即uint8类型的。那么结构体将会这样定义:
struct DeviceData {
quint8 number;
quint16 temperature;
quint16 humidness;
quint16 status;
};
测试代码:
QByteArray data;
DeviceData d;
d.number = 0x12;
d.temperature = 0x5678;
d.humidness = 0x4321;
d.status = 0x8756;
data.append(reinterpret_cast<char *>(&d), sizeof(DeviceData));
qDebug() &l