0

I am trying new the C++ socket programming. I am having some difficulty for understanding functionality of htons, htonl and related functions. I read some documents but still my questions are as follows,

for a single server and and single client I am using htons both side for the port number and the code is working fine. Even if I don't use these functions and both my server-clients are Intel based 64 bit machines, the codes are working fine. But what if multiple clients try to connect my server and the clients use different data storage format. For example, x86 is little-endian and ARM A-53 is both little- and big-endian and others, where some of them are 32 bits, 16 bits or 64 bits etc. My server is 64 bits. So I'm now confused which functions I have to use that uniformly serves all purpose ? Or, I have to always detect the client type and convert it's data format (port number) to 64 bit (as my server is 64 bit) and then use htonl() function to reach the server. It would be great someone please reply or points me out if I am on the wrong path ...

sandy
  • 283
  • 1
  • 7
  • 27
  • you could take a look at this: http://stackoverflow.com/questions/105252/how-do-i-convert-between-big-endian-and-little-endian-values-in-c – WalterM Oct 27 '15 at 11:45

2 Answers2

4

These functions convert from and to network byte order (that is in fact big endian). No matter on whether the architecture you're programming they will perform that task (if you're on a big endian architecture it will just be a no-op).

Using these consequently will make the code portable. Note though that you should not use htonl at both conversions. When you send data to another host you use htonl (host to network byte order) before you send the data and then ntohl (network to host byte order) when you receive.

Note that ntohl and htonl are not guaranteed (although I can't give an example) to be the same and you should therefore use the correct one.

skyking
  • 13,817
  • 1
  • 35
  • 57
2

It's good that you're asking the question. It shows that you're worrying about the right things.

Documentation here:

http://linux.die.net/man/3/htonl

note that the arguments and return types have specific sizes no matter which system you're on.

Richard Hodges
  • 68,278
  • 7
  • 90
  • 142
  • Hi Richard... Thanks for your reply. However, I still have confusions. Can you elaborate a little more ? One thing I understand from your answer that I don't need to convert the data in 64/32/16 bits as you said the arguments and return types have specific sizes. In that case, still I have question whether I have to detect every client so that I can decide for whom I am to use htons/htonl (argument) or ntohs/ntohl (return type) ? – sandy Oct 27 '15 at 13:51
  • With inter-system communications it is important to work with fixed sizes. Unless you have a very good reason to use large datatypes, the 32 and 16-bit types should be enough. In this case htonl and htons (and their reverse forms) should be enough. If you need to move 64-bit numbers, floating point numbers or strings around then you need a more formal protocol. One such protocol is google's protocol buffers which is not only cross-platform but also cross-language. have a look here: https://developers.google.com/protocol-buffers/ – Richard Hodges Oct 27 '15 at 14:11