QUdpSocket UDP socket writeDatagram readDatagram casting a struct (be carefull of padding)



  • Hello Mister/Miss QT,

    I want to SEND and RECEIVE a struct with QUdpSocket
    (as a translation of MSVS2013, see working code below)

    For example: the following struct:
    @
    typedef struct{
    unsigned short volgnummer;
    QByteArray payload;
    } UDPpacket;
    @

    I have working and tested code made in Visual Studio 2013 (see code below!) as that is what I'm really trying to achieve!!

    A simple (AND CORRECT) example of what I want to achieve:

    @
    void MyUDP::HelloUDP()
    {
    UDPpacket sendP;
    QByteArray send;
    send.append("UDP Message");
    sendP.payload = send;
    sendP.volgnummer = 1;

    socket->writeDatagram(SendP, QHostAddress::LocalHost, 1234);
    

    }

    void MyUDP::readPendingDatagrams()
    {
    UDPpacket receiveP;
    QByteArray buffer;
    QHostAddress sender;
    quint16 senderPort;
    buffer.resize(socket->pendingDatagramSize());
    socket->readDatagram(receiveP,SIZEOF(receiveP),&sender, &senderPort);
    }
    @

    Just using the normal way by means of QByteArray is working:

    @
    void MyUDP::HelloUDP()
    {
    UDPpacket sendP;
    QByteArray send;
    send.append("Als alles goed gaat is Error gelijk aan de hoeveelheid data dat is verzonden");
    sendP.payload = send;
    socket->writeDatagram(sendP.payload, QHostAddress::LocalHost, 1234);
    qDebug() << "Message: " << sendP.payload;
    }

    void MyUDP::readPendingDatagrams()
    {
    QByteArray buffer;
    QHostAddress sender;
    quint16 senderPort;
    buffer.resize(socket->pendingDatagramSize());
    socket->readDatagram(buffer.data(), buffer.size(),&sender, &senderPort);
    qDebug() << "Message: " << buffer;
    }
    @

    but as soon as I change it:

    @
    udp_packet tx_packet;
    udp_packet rx_packet;
    QByteArray Data;
    QByteArray buffer;
    QHostAddress sender;
    quint16 senderPort;

    tx_packet.volgnummer = (quint16)0;
    Data.append("Hello from UDP");
    tx_packet.real_payload = Data;
    
    socket->writeDatagram((char *)&tx_packet, sizeof(tx_packet), QHostAddress::LocalHost, 1234);
    socket->readDatagram ((char *)&rx_packet, sizeof(rx_packet), &sender, &senderPort);
    

    @

    I also tried const char * and even QByteArray * and several other options.

    [edit: added missing coding tags @ SGaist]



  • The following did the trick:

    memcpy(&tx_packet.MBC_payload, &buffer, sizeof(buffer));

    socket->writeDatagram((char *)&tx_packet, sizeof(tx_packet), QHostAddress::LocalHost, 1234);
    socket->readDatagram ((char *)&rx_packet, sizeof(rx_packet), &sender, &senderPort);

    qDebug() << "RECEIVED Message" << rx_packet.MBC_payload;
    gave the correct string back!

    BUT:

    • Watch out for PADDING of the compiler.
      (there are many items opened on this matter!

    AND

    certain functions will mess up (i.e. resizedatagram)

    So please be carefull



  • You should not really treat a QByteArray as raw data. Use the data() method to access a pointer to the data. I know this defeats your intention of having a struct with a header and then data, but this is not really a pattern that is very robust.

    A better mechanism would be to use a DataStream or TextStream wrapping a QByteArray to serialize your data and send the resulting byteArray over the wire.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.