字节序,顾名思义就是字节存放的顺序
字节序分为两种:
BIG-ENDIAN----大字节序
LITTLE-ENDIAN----小字节序
BIG-ENDIAN、LITTLE-ENDIAN与多字节类型的数据有关的比如int,short,long型,而对单字节数据byte却没有影响。
BIG-ENDIAN就是最低地址存放最高有效字节。
LITTLE-ENDIAN是最低地址存放最低有效字节。即常说的低位在先,高位在后。
Java中int类型占4个字节,一定要是“多字节类型的数据”才有字节序问题,汉字编码也有这个问题。请看下面4字节的例子:
比如 int a = 0x05060708
在BIG-ENDIAN的情况下存放为:
低地址------->高地址
字节号: 第0字节,第1字节,第2字节,第3字节
数 据: 05 , 06 , 07 , 08
在LITTLE-ENDIAN的情况下存放为:
低地址------->高地址
字节号: 第0字节,第1字节,第2字节,第3字节
数 据: 08 , 07 , 06 , 05
JAVA字节序:
指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。
主机字节序:
Intel的x86系列CPU是Little-Endian,而PowerPC 、SPARC和Motorola处理器是BIG-ENDIAN。
ARM同时支持 big和little,实际应用中通常使用little endian。是BIG-ENDIAN还是LITTLE-ENDIAN的跟CPU有关的,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN。
网络字节序:
4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit,最后是24~31bit。这种传输次序称作大端字节序(BIG-ENDIAN)。 TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序。
不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。
处理器 操作系统 字节排序
Alpha 全部 Little endian
HP-PA NT Little endian
HP-PA UNIX Big endian
Intelx86 全部 Little endian
所以在用C/C++写通信程序时,在发送数据前务必用htonl和htons去把整型和短整型的数据进行从主机字节序到网络字节序的转换,而接收数据后对于整型和短整型数据则必须调用ntohl和ntohs实现从网络字节序到主机字节序的转换。如果通信的一方是JAVA程序、一方是C/C++程序时,则需要在C/C++一侧使用以上几个方法进行字节序的转换,而JAVA一侧,则不需要做任何处理,因为JAVA字节序与网络字节序都是BIG-ENDIAN,只要C/C++一侧能正确进行转换即可(发送前从主机序到网络序,接收时反变换)。如果通信的双方都是JAVA,则根本不用考虑字节序的问题了。
java中转换字节序
方案一:通过ByteBuffer实现
方案二:自己写代码实现
ByteBuffer类中的order(ByteOrder bo) 方法可以设置 ByteBuffer 的字节序。
其中的ByteOrder是枚举:
ByteOrder BIG_ENDIAN 代表大字节序的 ByteOrder 。
ByteOrder LITTLE_ENDIAN 代表小字节序的 ByteOrder 。
ByteOrder nativeOrder() 返回当前硬件平台的字节序。