Functions of the ntohl/htonl class and 64-bit values

30.10.2010

As you know, the byte order in integer numbers which are represented by more than one byte may be different on different computers. There are computer systems where the most significant byte of a number has a lower address than the less significant byte (this is a so called big-endian byte order) and there are computer systems where the most significant byte of a number has a higher address than the less significant byte (little-endian byte order). When passing integer numerical data from a machine with one byte order to a machine with another byte order, we may be wrong in interpreting this information. To avoid this the notion of the network byte order was introduced, i.e. the byte order the numerical information should be presented in while being passed through the network (big-endian byte order was chosen). The integer numerical data are converted from the byte order accepted on the sender-computer into the network byte order by the user process, then they are passed through the network and are converted into the byte order accepted on the recipient computer by the destination-process. To convert integer numbers from the machine order into the network order and vice versa four functions are used: htons(), htonl(), ntohs(), ntohl().

Function description:

  • The function htonl converts an integer number from the byte order accepted on the computer into the network byte order.
  • The function htons converts an integer short number from the byte order accepted on the computer into the network byte order.
  • The function ntohl converts an integer number from the network byte order into the byte order accepted on the computer.
  • The function ntohs converts an integer short number from the network byte order into the byte order accepted on the computer.

The functions we have listed work with 16-bit and 32-bit values. As 64-bit systems appeared, it became necessary to implement the functions to work with 64-bit numbers. In some systems there exist the functions ntohll() and htonll() for that. But in some other systems there are no such functions. In this case you may implement this mechanism by yourself.

See the discussion "64 bit ntohl() in C++ ?" to learn some solutions of converting 64-bit values. Here is one such solution.

#define TYP_INIT 0 
#define TYP_SMLE 1 
#define TYP_BIGE 2 
 
unsigned long long htonll(unsigned long long src) { 
  static int typ = TYP_INIT; 
  unsigned char c; 
  union { 
    unsigned long long ull; 
    unsigned char c[8]; 
  } x; 
  if (typ == TYP_INIT) { 
    x.ull = 0x01; 
    typ = (x.c[7] == 0x01ULL) ? TYP_BIGE : TYP_SMLE; 
  } 
  if (typ == TYP_BIGE) 
    return src; 
  x.ull = src; 
  c = x.c[0]; x.c[0] = x.c[7]; x.c[7] = c; 
  c = x.c[1]; x.c[1] = x.c[6]; x.c[6] = c; 
  c = x.c[2]; x.c[2] = x.c[5]; x.c[5] = c; 
  c = x.c[3]; x.c[3] = x.c[4]; x.c[4] = c; 
  return x.ull; 
} 

References