QUdpSocket UDP socket writeDatagram readDatagram casting a struct (be carefull of padding)
-
wrote on 8 Sept 2014, 12:48 last edited by
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]
-
wrote on 16 Sept 2014, 13:05 last edited by
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
- Watch out for PADDING of the compiler.
-
wrote on 16 Sept 2014, 17:44 last edited by
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.