Search code examples
c++cqtqbytearray

Access UDP Datagram from a QByteArray


I'm not sure I understand how the QByteArray Object works as of yet (it's raw char data, right?), but here's my dilemma:

I'm trying to access data from a UDP datagram in a function. Code:

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

This frees up the buffer for other incoming data and allows me to process my current datagram.

As far as I can tell, I must store the data in a QByteArray, because any other attempt has made the compiler very cross with me. Regardless, the data stored in the QByteArray is a series of unsigned 16 bit values(commands) that I need to access. Can it be read directly out of the QByteArray, and if so, how? I've had no luck doing so. If not, what's the best way to convert the entire array to quint16 array so that I can process the incoming data? Thanks All!!


Solution

  • Once you have read the data with readDatagram, you need to access it in quint16 values.

    Two possible methods:

    1. Use a quint16 buffer and store directly into it:

      //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. Use a QByteArray and "unserialize" it to quint16 values. This approach is more complex but is cleaner, since you have options for interpreting data format, such as endianness.

      //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
      }