Qt Sockets and Endianness

I am writing a program that uses QUdpSocket to transmit data over a network. This is my first socket program, and I ran into an interesting Endianness problem.

My real question is, do I need to worry about Endianness when I use QNetwork as my socket library? If I really need to worry, what should I do to properly avoid problems with Endianness?

Thanks in advance.

+6
c ++ qt endianness networking sockets
source share
5 answers

Generally, you need to worry about endianness (byte-order) when you transfer integers larger than one byte from one computer to another. In C / C ++, this means that if you send something like a 16-bit, 32-bit, or 64-bit integer, you need to first convert the integer value to the network byte order (also known as Big-Endian). The host computer must then convert the incoming integers to a host byte order, which is any byte that the host uses initially. This is usually done using the htons and ntohs library functions, but with the Qt library you can also use the qToBigEndian and qFromBigEndian .

Please note that you don’t have to worry about the content when sending ASCII or UTF-8 text, as these formats consist of sequences of individual bytes rather than multi-byte data types.

+11
source share

If you transfer binary data between two machines with a different endianess, you may have to worry.

The network socket will simply send data unchanged. If other machines assume that the bytes sent are in a specific order, you need to do this.

If you transmit data in a known format, for example, an image, then in general the image has a header to show in which order it was written, and the reader / writer library will process it. If you are inventing your own binary format, then this is for you. You can also consider the size, how many bytes are int on another machine?

The good news is, most computers are Intel, and for most applications less data will be downloaded in ascii format.

+2
source share

Here is a simple test for great consistency, if you want it:

// This test assumes an int size of at least 2.

static const int testValue = 1;

#define is_bigendian () (((char) & testValue) == 0)

bool CD_is_bigendian (void) {return is_bigendian (); }

+1
source share

I know this was answered a long time ago, but I just thought I'd add it.

Instead of using the endian transform functions, you can use the QDataStream functionality (with any QIODevice), which is much simpler and more intuitive in my opinion. Of course, this would force you to use QDataStream for both the sender and the recipient, but in this case it’s worth it.

An example of use, for another sample sending image:

QDataStream & operator<< (QDataStream& stream, const QImage& image);
QDataStream & operator>> (QDataStream& stream, QImage& image);
(Both of them are already implemented in Qt.)

QTcpSocket *tcp = ...;
QImage img = ...;
QDataStream(tcp) << img;

+1
source share

Intel processors use a little endian. Most of the rest are big andian. The default byte order is large.

To check if the problem is with the content, send the value 0x12345678 and check if it makes it the same or 0x78563412. If the value at the receiving computer is a later value, then the judgment does not match between the two systems.

Check this wikipedia article for content information.

0
source share

All Articles