美文网首页
大字端(Big Endian)、小字端(Little Endia

大字端(Big Endian)、小字端(Little Endia

作者: 程就人生 | 来源:发表于2020-10-28 21:29 被阅读0次

前 言
最近在和传感器做对接,传感器的数据是通过DTU传给服务器的,DTU那边给的数据是01 00,但是服务器这边读到的就反了,读取的是00 01,这是为何呢?

不由地想起以前看过的一些文章,大字端(Big Endian)、小字端(Little Endian),会不会和这个有关系呢?

大字端(Big Endian)、小字端(Little Endian)的文章,还是不久之前看的,看完之后还不理解是什么意思,心里犯嘀咕,会有这种情况吗?有什么实际的用处呢?这不说来就来,字节读反了,不由就想起了大字端、小字端,还真和这个有关系。

服务器端使用的技术是Java的Netty框架,Netty里面的Bytebuf 对DTU端传递过来的数据进行接收读取,一个字节的直接读byte就可以了,两个字节的读short,既然涉及到大字端、小字端,除了readShort还有其他的方法吗,点进去看源码时,发现了还真有。

根据这段源码的注释,readShortLE()是从低字节开始读取,试了这个方法后,从DTU传过来的数据01 00,服务器使用readShortLE()之后,读取到的刚好和DTU传的数据一致。

readShort()虽没有写明,但测试证明是从大字端开始读取的,但以这样的方式进行读取,解析后的数据就对不上了。

今天就参考一些文章,来对大字端(Big Endian)、小字端(Little Endian)的概念进一步说明,以便加深印象,好记性不如烂笔头。

基 本 概 念

Byte:计算机中的Byte意为“字节”,8个二进制位构成1个字节(Byte),即1byte=8bit,字节是计算机处理数据的基本单位。

在上例中,硬件中转器DTU传给计算机的就是字节,有的数据占一个字节,有的数据占两个字节,甚至更多字节,三、四个字节,字节数一多就涉及到读取顺序。

大字端(BigEndian):按照从地址到地址的顺序,存放数据的位字节到位字节,就是高位字节存储在前面,低位字节存储在后面。

例如:整数(int)65262 用 十六进制 表示就是 0XFEEE,其中 0X 是十六进制的标识符。这个数字转化后有两个字节构成,分别为0XFE、0XEE。

在二进制文件中如果是按照大字端(Big Endian)的形式存储,那么在文件中的顺序是这样:0XFE、0XEE,符合人类的常规思维。

其中:0XFE 称为最高有效字节(most significant byte, MSB);

0XEE 称为最低有效字节(last significant byte, LSB)。

** 小字端(Little Endian): **按照从低地址到高地址的顺序,存放数据的低位字节到高位字节,就是低位字节在前面,高位字节在后面。

例如:0XFEEE,如果按照小字端(Little Endian)的形式存储,那么它的字节值存储顺序为0XEE、0XFE。

也就是说,大字端和小字端,存储数据时遵循不同的字节排列顺序,即字节序(Byte Order)不同。

二者的对比

整数65262的16进制表示: 0XFEEE

大字端 Big Endian 存储法: 0XFE 0XEE(默认)

小字端 Little Endian 存储法:0XEE 0XFE

最后上代码测试一下:

public static void main(String[] argo){
    //对十进制65262数字进行操作
    int n = 65262;
    //使用netty的Bytebuf申请两个字节的空间
    ByteBuf in = Unpooled.buffer(2);
    //以小字端的方式写入,模拟DTU传过来的参数
    in.writeShortLE(n);
    
    byte[] array = new byte[2];
    in.readBytes(array, 0, 2);
    System.out.println("第一个字节:" + Integer.toHexString(array[0] & 0xFF));
    System.out.println("第二个字节:" + Integer.toHexString(array[1] & 0xFF));
    
    //以小字端的方式写入,模拟DTU传过来的参数
    in.writeShortLE(n);
    
    //将读取到的2个字节转化为十进制数字
    System.out.println("以大字端的方式接收的数据为:" + (in.readShort() & 0xffff));
    
    //以小字端的方式写入,模拟DTU传过来的参数
    in.writeShortLE(n);
    //将读取到的2个字节转化为十进制数字
    System.out.println("以小字端的方式接收的数据为:" + (in.readShortLE() & 0xffff));
    
    //释放资源
    in.retain();
  }

测试结果:

最 后 总 结

基础性的知识,始终是基础的,该学的还是要学,可能刚开始时,并不能完全其意思,但是心里有了印象,遇到问题的时候能够想到,那离解决就八九不离十了。

感谢网友们的分享,所以我也要把自己的测试成果分享出来,越分享越快乐!

参考资料:

https://blog.csdn.net/a_Treasure/article/details/76991149

相关文章

网友评论

      本文标题:大字端(Big Endian)、小字端(Little Endia

      本文链接:https://www.haomeiwen.com/subject/xapcvktx.html