to convert a byte array from another machine which is big-endian, we can use:
long long convert(unsigned char data[]) {
long long res;
res = 0;
for( int i=0;i < DATA_SIZE; ++i)
res = (res << 8) + data[i];
return res;
}
if another machine is little-endian, we can use
long long convert(unsigned char data[]) {
long long res;
res = 0;
for( int i=DATA_SIZE-1;i >=0 ; --i)
res = (res << 8) + data[i];
return res;
}
why do we need the above functions? shouldn't we use hton at sender and ntoh when receiving? Is it because hton/nton is to convert integer while this convert() is for char array?
The
hton
/ntoh
functions convert between network order and host order. If these two are the same (i.e., on big-endian machines) these functions do nothing. So they cannot be portably relied upon to swap endianness. Also, as you pointed out, they are only defined for 16-bit (htons
) and 32-bit (htonl
) integers; your code can handle up to thesizeof(long long)
depending on howDATA_SIZE
is set.Through the network you always receive a series of bytes (octets), which you can't directly pass to
ntohs
orntohl
. Supposing the incoming bytes are buffered in the (unsigned) char arraybuf
, you could doshort x = ntohs(*(short *)(buf+offset));
but this is not portable unlessbuf+offset
is always even, so that you read with correct alignment. Similarly, to dolong y = ntohl(*(long *)(buf+offset));
you have to make sure that 4 dividesbuf+offset
. Yourconvert()
functions, though, don't have this limitation, they can process byte series at arbitrary (unaligned) memory address.