字节序

字节序

字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。

1.BIG-ENDIAN、LITTLE-ENDIAN跟多字节类型的数据有关的比如int,short,long型,而对单字节数据byte却没有影响。
比如 int a = 0x05060708
在BIG-ENDIAN的情况下存放为:  
字节号 0 1 2 3  数据 05 06 07 08  

在LITTLE-ENDIAN的情况下存放为:  
字节号 0 1 2 3  数据 08 07 06 05
又比如数字0x12345678,在两种不同字节序CPU中,其存储顺序如下所示:

Big Endian  
   低地址    高地址  
+-+-+-+-+-+-+-+-+-+-+
| 12 | 34 | 56 | 78 |  
+-+-+-+-+-+-+-+-+-+-+

Little Endian  
   低地址     高地址
+-+-+-+-+-+-+-+-+-+-+ 
| 78 | 56 | 34 | 12 |  
+-+-+-+-+-+-+-+-+-+-+ 

从上面两图可以看出,采用BIG-ENDIAN方式存储数据方便人类从字面理解数据,LITTLE-ENDIAN的数据较难裂解,因为LITTLE-ENDIAN主要是方便CPU处理数据,提高计算机效率。

2.BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有关的,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN、。IA架构(Intel、AMD)的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola处理器是Big-Endian。这其实就是所谓的主机字节序。而网络字节序是指数据在网络上传输时是大头还是小头的,在Internet的网络字节序是BIG-ENDIAN。所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。

3.所以在用C/C++写通信程序时,在发送数据前务必用htonl和htons去把整型和短整型的数据进行从主机字节序到网络字节序的转换,而接收数据后对于整型和短整型数据则必须调用ntohl和ntohs实现从网络字节序到主机字节序的转换,在Visual C++中,这四个函数被包含在头文件Winsock2.h里面,链接时需要链入Ws2_32.lib[1]。如果通信的一方是JAVA程序、一方是C/C++程序时,则需要在C/C++一侧使用以上几个方法进行字节序的转换,而JAVA一侧,则不需要做任何处理,因为JAVA字节序与网络字节序都是BIG-ENDIAN,只要C/C++一侧能正确进行转换即可(发送前从主机序到网络序,接收时反变换)。如果通信的双方都是JAVA,则根本不用考虑字节序的问题了。  4.如果网络上全部是相同字节序的计算机那么不会出现任何问题,但由于实际有大量不同字节序的计算机,所以如果不对数据进行转换,就会出现大量的错误。

5.文章开头所提出的问题,就是因为程序运行在X86架构的PC SERVER上,发送数据的一端用C实现的,接收一端是用JAVA实现的,而发送端在发送数据前未进行从主机字节序到网络字节序的转换,这样接收端接收到的是LITTLE-ENDIAN的数据,数据解释自然出错。  具体数据如下,实际发送的数据为23578  发送端发送数据: 1A 5C  接收端接收到数据后,按BIG-ENDIAN进行解释得到的则是6748,显然不是正确的数据

你可能感兴趣的:(字节序)