unsigned short* pname = (unsigned short*)(buf + buf_offset);/*sequence problem?*/
unsigned short pointer_offset = ntohs(*pname) & COMPRESSION_MASK;
这里,buf_offset == 0。buf的内容是[c0] [0c]。但是,*pname是[0x0cc0]。问题是什么?谢谢你。
unsigned short* pname = (unsigned short*)(buf + buf_offset);/*sequence problem?*/
unsigned short pointer_offset = ntohs(*pname) & COMPRESSION_MASK;
这里,buf_offset == 0。buf的内容是[c0] [0c]。但是,*pname是[0x0cc0]。问题是什么?谢谢你。
这取决于您的平台,大端/小端,您应该更改字节顺序。
#ifdef _BIG_ENDIAN_
// revers bytes order
#endif
ntohs() 将字节顺序交换为大端
正如其他人指出的那样,您发布的代码不可移植。这不仅仅是因为字节序的原因。由于无效对齐,从char *
to 转换unsigned short *
也可能导致总线错误。此外,an 中可能有填充位unsigned short
会导致您的程序行为不端,或者 anunsigned short
可能小于或大于“2 个字节”,具体取决于CHAR_BIT
实现的选择。总体问题是类型的内部表示,您可以通过使用行为相同的运算符来避免这个问题,而不管内部表示如何。也许你的意思是:
unsigned short offset = (unsigned char) buf[0];
offset *= (UCHAR_MAX + 1);
offset += (unsigned char) buf[1];
offset &= COMPRESSION_MASK;
如果你想要大端,你必须明确声明你想要它。通过相乘buf[0]
和相加buf[1]
,我指定它buf[0]
比 更重要buf[1]
,因此我明确指定我想要大端序。乘法和加法在每个 C 实现中的工作方式都是一样的,并且不存在对齐问题。
反转转换:
unsigned char buf[2] = { offset / (UCHAR_MAX + 1), offset % (UCHAR_MAX + 1) };
很高兴看到在不关心内部表示的情况下编写更多代码!
正如加布里埃尔所说,
ntohs() 将 u_short 从 TCP/IP 网络字节顺序转换为主机字节顺序(在 Intel 处理器上是 little-endian)。
ntohs 函数以主机字节顺序返回值。如果传递的参数已经是主机字节顺序,那么这个函数会反转它。由应用程序决定是否必须颠倒字节顺序。