何时使用hton / ntoh以及何时自己转换数据?

时间:2014-02-24 19:13:30

标签: endianness

从另一台big-endian机器转换字节数组,我们可以使用:

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;
}

如果另一台机器是little-endian,我们可以使用

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;
}

为什么我们需要上述功能?我们不应该在收件人时使用hton而在收到时使用ntoh吗?是因为当这个convert()用于char数组时,hton / nton是转换整数吗?

2 个答案:

答案 0 :(得分:6)

hton / ntoh函数在网络订单主机订单之间进行转换。如果这两个是相同的(即,在大端机器上),这些功能什么都不做。所以他们不能依赖交换字节顺序。另外,正如您所指出的,它们仅针对16位(htons)和32位(htonl)整数定义;根据{{​​1}}的设置方式,您的代码最多可以处理sizeof(long long)

答案 1 :(得分:0)

通过网络,您始终会收到一系列字节(八位字节),您无法直接将它们传递给ntohsntohl。假设传入的字节缓冲在(无符号)char数组buf中,则可以执行 short x = ntohs(*(short *)(buf+offset)); 但这是不可移植的,除非buf+offset始终是偶数,以便您以正确的 alignment 进行阅读。同样,要做 long y = ntohl(*(long *)(buf+offset)); 您必须确保4除以buf+offset。不过,您的convert()函数没有此限制,它们可以在任意(未对齐的)内存地址处处理字节序列。