前 言
最近在和传感器做对接,传感器的数据是通过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();
}
测试结果:
最 后 总 结
基础性的知识,始终是基础的,该学的还是要学,可能刚开始时,并不能完全其意思,但是心里有了印象,遇到问题的时候能够想到,那离解决就八九不离十了。
感谢网友们的分享,所以我也要把自己的测试成果分享出来,越分享越快乐!
参考资料:
网友评论