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

2

8

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 ?

Dentelle answered 23/1, 2014 at 14:47 Comment(3)
No, you only found a little-endian implementation of htonl(). The big-endian implementation is a no-op. Which implementation your code ends up using depends on the platform.March
In that case, htonl() programmer should aware of the machine architecture and write the code. This will tightly couple the code with the machine architecture thereby removing portability. Is that correct /Dentelle
@AnilKumarKK Of course. The implementation is processor-dependent.Puritan
W
9

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.

Wax answered 23/1, 2014 at 14:52 Comment(2)
Does that mean that htonl() on Big-endian machine not do anything as the bytes are already in Network order(Big-endian) ?Dentelle
@AnilKumarKK yes. on big-endian machines, htonl is a no-op. if you're lucky, the compiler optimizes it out entierly for runtime. if you're less lucky, its just a waste of cpu. (call, mov, push, retn)Frowzy
L
6

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.

Larceny answered 23/1, 2014 at 14:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.