QDataStream和quint16序列化的怪异

QDataStream and quint16 serialization weirdness

本文关键字:序列化 quint16 QDataStream      更新时间:2023-10-16

我写了一个小的Packet类,由一些quint8,quint16,QByteArrays和一个quint32组成,它有一个toByteArray()方法来返回对象的序列化版本,符合协议规范。

数据包规格

  • 协议标识符 [4 字节](版本 1 = 0x74697331)
  • 会话 ID,一个带有时间戳 + 用户 IP 的 MD5 哈希。[16 字节]
  • 命令 ID [1 字节]
  • 参数大小 [2 字节]
  • 参数 [1-8,192 字节]
  • CRC-B (X-25) [2 字节]

大多数数据序列化正常。例外是最后一个 quint16(我的 crc),它似乎被破坏了。

我不认为问题出在我的班级的声明中。我在此代码示例中重新创建了序列化函数,该函数演示了我收到的错误,没有我的数据包类。 (但相同的最终 QByteArray 布局)

(更多) 最小可重现的测试用例

#include <iostream>
#include <QByteArray>
#include <QDebug>
using namespace std;
int main()
{
    QByteArray arr;
    quint32 m_protocolId = 0x74697331;
    QByteArray m_sessionId;
    m_sessionId.resize(16);
    m_sessionId.fill(0);
    quint8 m_commandId = 0x1;
    quint16 m_argsSize = 0x0e;
    QByteArray args;
    args.append("test").append('');
    args.append("1234qwer").append('');
    quint16 m_crc;
    m_crc = 0xB5A2;
    QDataStream out(&arr, QIODevice::WriteOnly);
    out.setByteOrder(QDataStream::LittleEndian);
    out << m_protocolId;
    out.writeRawData(m_sessionId.data(), 16);
    out << m_commandId;
    out << m_argsSize;
    out.writeRawData(args.data(), args.length());
    out << m_crc;
    foreach (char c, arr)
    {
        qDebug() << QString::number((int)c, 16).toAscii().data();
    }
    return 0;
}

这是我得到的输出:

73697400000000000000001e074657374031323334717765720fffffffff

最后两个应该是0xa2,0xb5。我想这是某种对齐问题。有没有办法在仍然符合数据包规范的同时纠正此问题?

我认为您只需要调整调试输出。尝试:

..
foreach (unsigned char c, arr)
..