When I send a integer variable from one process to other through socket, and then printing the value at received end, the value is still the same without using ntohl/htonl, then where do I need to use these functions other than initializing socket structures. I understand litte/big endian. But why do we need to convert port and IP nos to host/network byte order when value remains the same. Please explain in detail how the integer is tranferred over network?
If you want your program to be portable, then any time you send an integer greater than 1 byte in size over the network, you must first convert it to network byte order using htons
or htonl
, and the receiving computer must convert it to host byte order using ntohs
or ntohl
.
In your case, the reason the value is still the same is probably because the sending computer and the receiving computer are of the same endianness. In other words, the sending computer and the receiving computer you're working with are both little endian (or big endian, whatever the case may be.)
But if you want your program to be portable, you can't rely on this to always be the case. One day, for example, the sending computer may be an Intel x86, and the receiving may be a Sun SPARC, and then your program will fail if you don't use htons
.
If you want to send data from an x86 or amd64 machine to a machine with a PowerPC processor, in binary format you'll quickly see that your data encounters the "NUXI problem" as the different processors treat the integers differently and appear to swap the bytes. (They don't actually swap the bytes -- they just work with them in a different order.)
When working on x86 or amd64, the least-significant byte comes first in memory (this way you can perform addition from lower to higher memory addresses). The PowerPC puts the most-significant byte first in memory (this way you can sort numbers based on the bytes that come earlier in memory -- a string sort and an integer sort can be exactly the same.)
It remaimns the same because on your architecture the network order is the same as the native order. If you never anticipate compiling your code for another architecture you could omit the hton/ntoh calls. Your code would then not be portable.