Literally confused about htonl(). In so many links I found that code to do htonl is :
#define HTONL(n) (((((unsigned long)(n) & 0xFF)) << 24) | \
((((unsigned long)(n) & 0xFF00)) << 8) | \
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
((((unsigned long)(n) & 0xFF000000)) >> 24))
If the same code is ran on both the machines, it is going to swap the byte orders. Example : uint32_t a = 0x1;
On Little Endian:
100 1
101 0
102 0
103 0
After htonl(a)
100 0
101 0
102 0
103 1
============================================ On Big Endian machine:
100 0
101 0
102 0
103 1
After htonl(a)
100 1
101 0
102 0
103 0
Does that mean that htonl() will change the order of the bytes irrespective of machine architecture ?
If you use it correctly then it should not swap bytes on big endian machines.
htonl
is defined in a header which is architecture specific. Normally machine/endian.h
will include your architecture specific header. If you redefine it then it will do what you set it to. If you want the real behaviour then you should always use the right architecture header. On big endian machines it's a no op. On little endian machines it's often linked to a specific processor instruction.
I think key to understanding the function is understanding its name.
The function htonl is:
H ost to
N etwork L ong
That is: it converts from the Host order to the Network defined (Big Endian) order.
Different hosts could have different representations:
Whatever the machine format, this function converts to a common Network format so the data can be easily, reliably sent to other machines on the network that may have different representations.
Once you understand the concept of Host / Network, then it shouldn't be hard to understand that Network order is Big-Endian, and any Host that is Big-Endian doesn't need any conversion at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With