2
votes

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!!

1
QByteArray is an array of bytes. To convert to a 16 bit unsigned integer value, you have to take two adjacent bytes from the buffer and use buffer[n]*0xFF+buffer[n+1] if the sender uses a big-endian system. Change the order if it is in little-endian system.R Sahu

1 Answers

4
votes

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
    }