Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DOES htonl() change byte order on BIG ENDIAN machine?

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:

Addr value

100   1
101   0
102   0
103   0

After htonl(a)

Addr value

100   0
101   0
102   0
103   1

============================================ On Big Endian machine:

Addr value

100   0
101   0
102   0
103   1

After htonl(a)

Addr value

100   1
101   0
102   0
103   0

Does that mean that htonl() will change the order of the bytes irrespective of machine architecture ?

like image 333
Anil Kumar K K Avatar asked Jan 23 '14 14:01

Anil Kumar K K


Video Answer


2 Answers

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.

like image 164
Sergey L. Avatar answered Sep 21 '22 05:09

Sergey L.


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:

  • Big-Ending
  • Little-Endian
  • even some other representation (imagine some new machine that works on base-3, or has Middle-Outwards representation?

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.

like image 23
abelenky Avatar answered Sep 22 '22 05:09

abelenky