我们知道endian与计算机存储数据的方式有关。大端计算机体系结构包括IBM 370,Motorola 68000和Sun Sparc。小端计算机包括intel系列(80486,pentium等)和VAX。
由于JVM,Java始终是Big-Endian。 由于协议,网络应始终为Big-Endian。
答案 0 :(得分:8)
htonl
,那么您将无法在小端机器上创建有效数据包。htonl
等等(或者使用您使用的任何语言的等效语句)。因为即使你今天拥有一个同质的环境,几乎可以肯定,将来这种情况会发生变化。更具体地说,您应该始终将转换为尽可能靠近界面,并在一个地方 。如果您的代码库中存在遍布字节顺序转换调用,则很难判断您的代码是否合理。
答案 1 :(得分:1)
二进制计算机之间传输的数据取决于Endian排序。
C,C ++和C#对Endianess没有任何要求或要求。
网络应遵循协议。在按协议输入和写出数字后,这些数字将转换为内部格式。它们可以是任何内部处理格式。
在计算机之间传输二进制数据时,只关心Endianess,无论是存储在文件中还是立即传输。
浮点数遭遇类似问题。
许多语言都不关心Endianness。
答案 2 :(得分:1)
严格地说Java使用与运行它的硬件相同的endian,但它没有为JVM用户显示,因为你无法访问Java中的原始内存。
答案 3 :(得分:0)
以非常抽象的术语来说,当您序列化数据时,必须具有字节序感知和特定于字节序的唯一时间。这具有非常精确的含义,实际上在某种程度上由C ++中的语言标准涵盖:
在程序的主要部分中,数据来自某个类型的变量,写为T x;
。到目前为止便携;你的程序总是做你想要的,你不需要知道内部如何表示x
。您知道x
的内存从&x
开始,并且sizeof(T)
字节长,但您不知道其他任何内容。如果您确实想要查找,则必须将&x
从T*
投射到unsigned char*
。
虽然一般禁止使用指针(它被称为“类型双关语”),但标准明确允许此特定强制转换。转换为char-pointer是将序列化数据从opaque类型T
转换为实际字节流的唯一方法。正是在这个时刻你必须知道字节序(或更一般地说,表示),因为你必须知道字节流构成T
的内部表示的顺序。 / p>
对于整数类型,您可以在不转换指针的情况下执行,但接口仍处于从字节流到值的转换:
unsigned char buf[sizeof(unsigned int)];
unsigned int value;
buf[0] = value; buf[1] = value >> 8; buf[2] = value >> 16; /*...*/ // We chose an endianness!
value = buf[0] + (buf[1] << 8) + (buf[2] << 16) + ... ; // ditto
在使用read
和write
等操作时,您会发现需要将值转换为字节流,反之亦然,通常与文件,流或套接字相关联。
注意,对于整数值,我们从不需要知道程序本身的字节顺序 - 我们只需要知道字节流使用的字节顺序!