PDA

View Full Version : Parsing UDP datagram fields



catto
17th February 2011, 17:17
Hello,

I am writing an application which has to receive UDP datagrams originated from an external source. I read the datagrams from the socket using QByteArray. The datagram has several fields, a 2-byte number, a 4-byte number and a textual message. I can read the textual message with the following code:



QByteArray buffer;
// ...
// read datagram from socket
// ...
QString message = QString::fromAscii(buffer.mid(6, 10));


But the parsing of the other fields of the datagram doesn't work. For example:



bool correct = true;
quint16 cmd = buffer.mid(0, 2).toUShort(&correct);
// correct is false after conversion


I assume I can't use QDataStream to get the individual fields, as the data is not being serialized to a QDataStream on the other end of the comunication. Could anyone point out what I am doing wrong? Is there maybe a better way to parse the different fields of a datagram in order to process them on the receiving end?

Any help would be much appreciated.

Thank you,
catto

marcvanriet
17th February 2011, 19:25
Hi,

I guess you want the 2 binary values at location 0 and 1 of the buffer to be interpreted as a 16-bit number ? Then just do something like nValue = (unsigned int)buffer[0] * 256 + (unsigned int)buffer[1]). Mind endianess though (which byte is MSB and which is LSB).

The toUShort function is for converting something written as text in the buffer to an integer. See the documentation for QString::toULong() for an example.

Best regards,
Marc

catto
18th February 2011, 15:40
Thanks marcvanriet, interpret binary values of the buffer as numbers is exactly what I need, as I have to compare them with hexadecimal constants. What troubles me is exactly what you mention about minding endianess. Isn't there a way to parse the datagram fields in a platform-independant way?

marcvanriet
18th February 2011, 17:18
Hi,

Endianess is defined in the IP and UDP protocol, so you can look this up (don't know it by heart). I usually just write my own getInt() or something method. It's just a few lines long. Its no use to make something platform independent (so targeted to the processor you use) if the protocol defines something else.

Best regards,
Marc

mcosta
18th February 2011, 17:29
you can use QDataStream.
Warning: As default QDataStream uses BigEndian

catto
19th February 2011, 11:44
Thank you marcvanriet, mcosta.

mcosta, can you use QDataStream even if the other end of the communication is not using QDataStream to serialize data (it isn't even a Qt application) ?

mcosta
21st February 2011, 14:21
Yes, if you use only C/C++ base types such as char, int, ecc...

catto
23rd February 2011, 20:16
Thank you very much.