【问题标题】:Access UDP Datagram from a QByteArray从 QByteArray 访问 UDP 数据报
【发布时间】:2014-08-07 23:28:37
【问题描述】:

我不确定我是否了解 QByteArray 对象的工作原理(它是原始 char 数据,对吗?),但这是我的困境:

我正在尝试从函数中的 UDP 数据报访问数据。代码:

QByteArray buffer;  
buffer.resize(udpSocket->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpSocket->readDatagram(buffer.data(), buffer.size(), &sender, &senderPort);

这为其他传入数据释放缓冲区,并允许我处理我当前的数据报。

据我所知,我必须将数据存储在 QByteArray 中,因为任何其他尝试都会使编译器与我产生矛盾。无论如何,存储在 QByteArray 中的数据是我需要访问的一系列无符号 16 位值(命令)。是否可以直接从 QByteArray 中读取,如果可以,如何读取?我没有运气这样做。如果没有,将整个数组转换为 quint16 数组以便我可以处理传入数据的最佳方法是什么?谢谢大家!!

【问题讨论】:

  • QByteArray 是一个字节数组。要转换为 16 位无符号整数值,您必须从 buffer 获取两个相邻字节,如果发送方使用大端系统,则使用 buffer[n]*0xFF+buffer[n+1]。如果是 little-endian 系统,请更改顺序。

标签: c++ c qt qbytearray


【解决方案1】:

使用 readDatagram 读取数据后,您需要以 quint16 值访问它。

两种可能的方法:

  1. 使用 quint16 缓冲区并直接存储到其中:

    //Set 1024 to any large enough size
    QVector<quint16> buffer(1024);
    qint64 readBytes = udpSocket->readDatagram((char*)buffer.data(),
                                               buffer.size()*sizeof(qint16),
                                               &sender,
                                               &senderPort);
    buffer.resize(readBytes/sizeof(quint16));
    //Now buffer contains the read values, nothing more.
    
  2. 使用 QByteArray 并将其“反序列化”为 quint16 值。这种方法更复杂但更简洁,因为您可以选择解释数据格式,例如字节序。

    //Set 2048 to any large enough size
    QByteArray buffer(2048);
    qint64 readBytes = udpSocket->readDatagram(buffer.data(),
                                               buffer.size(),
                                               &sender,
                                               &senderPort);
    buffer.resize(readBytes);
    
    QDataStream dataStream(&buffer, QIODevice::ReadOnly);
    
    //Configure QDataStream here, for instance:
    //dataStream.setByteOrder(QDataStream::LittleEndian);
    
    while(!dataStream.atEnd())
    {
        quint16 readValue;
        dataStream >> readValue;
    
        //do something with readValue here
    }
    

【讨论】:

  • 抱歉,我遗漏了反映您的评论的额外代码,以保持这篇文章的简短。我已经更正了。
  • 我从未使用过 QDataStream,所以我假设它是一个处理数据转换的工具?我会查查的。无论如何,我的 C++ 有点不稳定(newb)所以我会问 - readValue 是一个 16 位数组,包含存储在 QByteArray 中的数据?
  • @galinette:UDP 数据报大小不应大于 512 字节(碎片问题)。理论上,UDP 数据报的最大值为 65507 字节 (IPv4)。
  • 是的,QDataStream 是一个用于编码/解码二进制数据的类。
  • readValue 不是一个数组,它是一个无符号的 16 位整数。这是一个循环,因此在每次迭代中,您都有下一个 16 位值,直到所有内容都被读取。你可以随意填充 16 位数组。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多