Reputation: 301
I'm not sure how to use hton()
. The theory is that any data sent over the network should be in network byte (i.e. big-endian) format. Suppose client A supports big-endian and B supports little-endian. I'm sending data from A to B and the data is read as multibyte. Then in the network we need to convert data to network byte order using htonl()
and htons()
. Since client A is already big-endian, htonl()
and htons()
return the same output. But B is little-endian, so those functions reverse the order. Given that, how can we say that adhering to a common format (i.e. big-endian) is a solution to the problem when big- and little-endian machines need to communicate?
Upvotes: 3
Views: 4149
Reputation: 91017
I'll try it the other way, showing the whole flow:
Sending 0x44332211
over the wire always happens as 44 33 22 11
. The sender's htonl()
ensures that, either by reverting the order of the bytes (on LE machines) or by just leaving them the way they are (on BE machines). The receiver turns the 44 33 22 11
into 0x44332211
with ntohl()
- again, either by reverting them or leaving them.
The mentionned functions {hton,ntoh}{l,s}()
help programming in a portable way: no matter if the program tuns on a LE or BE machine, they always work the way they should. Thus, even on BE machines the functions should be called, even if they are noops.
Example:
A (BE) wants to send 0x44332211
to B (LE).
0x44332211
in memory as 44 33 22 11
.htonl()
as the program has been written to be portable.44 33 22 11
and sent over the wire.44 33 22 11
and puts it through ntohl()
.11 22 33 44
from ntohl()
and puts it into the respective variable - which then results to 0x44332211
as wanted.Again, the need for always calling these function saves you from thinking about which kind of machine you are programming for - just program for all kinds of machines and call each of these function when they are needed.
The same example can be expressed without knowing if A or B are BE or LE:
0x44332211
in memory.htonl()
so that the number is sent as 44 33 22 11
over the wire.
Whether this is done by reverting or by leaving it is determined by the endianness of host B.44 33 22 11
and puts it through ntohl()
. This one reverses it or not, depending on the endianness of host B.0x44332211
as wanted.Upvotes: 7
Reputation: 175355
I think you're thinking that client B seeing the bytes in "reversed order" means that they're wrong. The bytes will be in reverse order compared to client A, but that's because client A interprets integers backwards from client B; both will still interpret it as the same number in the end. For example, one machine would represent the number 4 as 00 00 00 04
. The other would represent it as 04 00 00 00
, but both would still see it as a 4 -- if you add 1 to it you're going to get 00 00 00 05
and 05 00 00 00
, respectively. The hton
/ntoh
functions exist because there's no way to look at a number and know if it's big- or little-endian, so the receiver can't be sure which way to interpret the bytes
Upvotes: 1