【问题标题】:QDataStream and quint16 serialization weirdnessQDataStream 和 quint16 序列化怪异
【发布时间】:2012-04-25 10:56:54
【问题描述】:

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

数据包规范

  • 协议标识符 [4 字节](版本 1 = 0x74697331)
  • 会话 ID,一个用时间戳 + 用户 IP 加盐的 MD5 哈希。 [16 字节]
  • 命令 ID [1 字节]
  • 参数大小 [2 字节]
  • Args [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('\0');
    args.append("1234qwer").append('\0');
    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;
}

这是我得到的输出:

73 69 74 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 e 0 74 65 73 74 0 31 32 33 34 71 77 65 72 0 fffffffffffffa2 ffffffffffffffb5

最后两个应该是0xa2、0xb5。我想这是某种对齐问题。有什么方法可以在符合数据包规范的同时纠正这个问题?

【问题讨论】:

    标签: c++ qt serialization qbytearray


    【解决方案1】:

    我认为你只需要调整你的调试输出。试试:

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

    【讨论】:

    • 是的,就是这样;非常感谢! (我还必须在 QString::number() 调用中转换为 unsigned int )。叹息,现在感觉我浪费了几个小时..
    猜你喜欢
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多