Java字节序

来源:互联网 发布:python 读取exe文件 编辑:程序博客网 时间:2024/05/28 06:07

 以下对BIG-ENDIAN、LITTLE-ENDIAN的解释正好弄反了!!!!
  BIG-ENDIAN(大字节序、高字节序)
  LITTLE-ENDIAN(小字节序、低字节序)
  主机字节序
  网络字节顺序
  JAVA字节序
  1.BIG-ENDIAN、LITTLE-ENDIAN跟多字节类型的数据有关的比如int,short,long型,而对单字节数据byte却没有影响。BIG-ENDIAN就是低位字节排放在内存的低端,高位字节排放在内存的高端。而LITTLE-ENDIAN正好相反。 
  比如 int a = 0x05060708 
  在BIG-ENDIAN的情况下存放为: 
  字节号 0 1 2 3 
  数据 05 06 07 08 
  在LITTLE-ENDIAN的情况下存放为: 
  字节号 0 1 2 3 
  数据 08 07 06 05 
  2.BIG-ENDIAN、LITTLE-ENDIAN、跟CPU有关的,每一种CPU不是BIG-ENDIAN就是LITTLE-ENDIAN、。IA架构的CPU中是Little-Endian,而PowerPC 、SPARC和Motorola处理器。这其实就是所谓的主机字节序。而网络字节序是指数据在网络上传输时是大头还是小头的,在Internet的网络字节序是BIG-ENDIAN。所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。 
  3.所以在用C/C++写通信程序时,在发送数据前务必用htonl和htons去把整型和短整型的数据进行从主机字节序到网络字节序的转换,而接收数据后对于整型和短整型数据则必须调用ntohl和ntohs实现从网络字节序到主机字节序的转换。如果通信的一方是JAVA程序、一方是C/C++程序时,则需要在C/C++一侧使用以上几个方法进行字节序的转换,而JAVA一侧,则不需要做任何处理,因为JAVA字节序与网络字节序都是BIG-ENDIAN,只要C/C++一侧能正确进行转换即可(发送前从主机序到网络序,接收时反变换)。如果通信的双方都是JAVA,则根本不用考虑字节序的问题了。 
  4.如果网络上全部是PowerPC,SPARC和Motorola CPU的主机那么不会出现任何问题,但由于实际存在大量的IA架构的CPU,所以经常出现数据传输错误。 
  5.文章开头所提出的问题,就是因为程序运行在X86架构的PC SERVER上,发送数据的一端用C实现的,接收一端是用JAVA实现的,而发送端在发送数据前未进行从主机字节序到网络字节序的转换,这样接收端接收到的是LITTLE-ENDIAN的数据,数据解释自然出错。 
  具体数据如下,实际发送的数据为23578 
  发送端发送数据: 1A 5C 
  接收端接收到数据后,按BIG-ENDIAN进行解释具体数据是多少?你们自己去计算并比较吧!
  ===============================================================================================
  Big Endian and Little Endian 
  谈到字节序的问题,必然牵涉到两大CPU派系。那就是Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存储数据,而x86系列则采用little endian方式存储数据。那么究竟什么是big endian,什么又是little endian呢? 
  其实big endian是指低地址存放最高有效字节(MSB),而little endian则是低地址存放最低有效字节(LSB),即常说的低位在先,高位在后。 
  用文字说明可能比较抽象,下面用图像加以说明。比如数字0x12345678在两种不同字节序CPU中的存储顺序如下所示: 
  Big Endian 
  低地址 高地址 
  -----------------------------------------> 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
  | 12 | 34 | 56 | 78 | 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
  Little Endian 
  低地址 高地址 
  -----------------------------------------> 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
  | 78 | 56 | 34 | 12 | 
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
  从上面两图可以看出,采用big endian方式存储数据是符合我们人类的思维习惯的。而little endian,!@#$%^&*,见鬼去吧 -_-||| 
  为什么要注意字节序的问题呢?你可能这么问。当然,如果你写的程序只在单机环境下面运行,并且不和别人的程序打交道,那么你完全可以忽略字节序的存在。但是,如果你的程序要跟别人的程序产生交互呢?尤其是当你把你在微机上运算的结果运用到计算机群上去的话。在这里我想说说两种语言。C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而JAVA编写的程序则唯一采用big endian方式来存储数据。试想,如果你用C/C++语言在x86平台下编写的程序跟别人的JAVA程序互通时会产生什么结果?就拿上面的 0x12345678来说,你的程序传递给别人的一个数据,将指向0x12345678的指针传给了JAVA程序,由于JAVA采取big endian方式存储数据,很自然的它会将你的数据翻译为0x78563412。什么?竟然变成另外一个数字了?是的,就是这种后果。因此,在你的C程序传给JAVA程序之前有必要进行字节序的转换工作。 

  无独有偶,所有网络协议也都是采用big endian的方式来传输数据的。所以有时我们也会把big endian方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。ANSI C中提供了四个转换字节序的宏。

 

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 宝宝吐了5 6次了怎么办 7岁儿童吃了就吐怎么办 狗狗拉稀呕吐不吃饭只喝水怎么办 宝宝吃坏肚子上吐下泄怎么办 一岁宝宝又吐又拉怎么办 八个月宝宝吃什么吐什么怎么办 九个月宝宝吃什么吐什么怎么办 三岁宝宝吃什么吐什么怎么办 2岁宝宝又拉又吐怎么办 6岁儿子又吐又拉怎么办 2岁宝宝吃了就吐怎么办 宝宝吃饱了就吐吐了在吃怎么办 3岁宝宝吃了就吐怎么办 6岁儿童又吐又拉怎么办 还没满月的宝宝肚子胀气怎么办 婴儿拉屎有粘液像果冻状怎么办 宝宝不爱吃饭怎么办吃就吐出来 19天的宝宝生理性腹泻怎么办 33天的婴儿生理性腹泻怎么办 两个多月宝宝生理性腹泻怎么办 3岁儿童又吐又拉怎么办 宝宝两岁了突然说话有点口吃怎么办 姜文怎么克服口吃 说话结巴怎么办 慢性咽炎嗓子干哑说话费劲怎么办 感冒后嗓子不疼 说话费劲怎么办 小孩子在幼儿园内向老尿裤子怎么办 五岁宝宝总是抽鼻子有黄鼻涕怎么办 2岁宝宝头有大人的那么大怎么办 一岁四个月宝宝不理人不说话怎么办 两岁七个月还不会说话怎么办 2岁3个月宝宝说话结巴怎么办 两周的宝宝突然说话结巴怎么办 宝宝3岁半了说话口吃怎么办? 四十天的宝宝吐奶严重怎么办 宝宝吐奶从鼻子喷出来怎么办 六个多月宝宝吐奶一股酸味怎么办 50天的宝宝吃了就吐怎么办 微信语音群聊超过9人怎么办 四个月宝宝母乳不够不喝奶粉怎么办 四个月的宝宝母乳不够吃怎么办 火山直播十多天了还都是假人怎么办