- 浏览: 753170 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
萨琳娜啊:
Java读源码之Netty深入剖析网盘地址:https://p ...
使用JAVA操作netty框架 -
小灯笼:
Netty源码剖析视频教程网盘地址:https://pan.b ...
使用JAVA操作netty框架 -
luckywind:
请问怎么下载那个svn上的源码啊?
本地调试Hbase源码详解 -
heng123:
Netty视频教程https://www.douban.com ...
使用JAVA操作netty框架 -
kongdong88:
Netty简单应用与线上服 ...
使用JAVA操作netty框架
字节序,顾名思义就是字节存放的顺序
字节序分为两种:
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实现
方案二:自己写代码实现
- package com.xxx;
- /**
- * 通信格式转换
- *
- * Java和一些windows编程语言如c、c++、delphi所写的网络程序进行通讯时,需要进行相应的转换 高、低字节之间的转换
- * windows的字节序为低字节开头 linux,unix的字节序为高字节开头 java则无论平台变化,都是高字节开头
- */
- public class FormatTransfer {
- /**
- * 将int转为低字节在前,高字节在后的byte数组
- *
- * @param n
- * int
- * @return byte[]
- */
- public static byte[] toLH(int n) {
- byte[] b = new byte[4];
- b[0] = (byte) (n & 0xff);
- b[1] = (byte) (n >> 8 & 0xff);
- b[2] = (byte) (n >> 16 & 0xff);
- b[3] = (byte) (n >> 24 & 0xff);
- return b;
- }
- /**
- * 将int转为高字节在前,低字节在后的byte数组
- *
- * @param n
- * int
- * @return byte[]
- */
- public static byte[] toHH(int n) {
- byte[] b = new byte[4];
- b[3] = (byte) (n & 0xff);
- b[2] = (byte) (n >> 8 & 0xff);
- b[1] = (byte) (n >> 16 & 0xff);
- b[0] = (byte) (n >> 24 & 0xff);
- return b;
- }
- /**
- * 将short转为低字节在前,高字节在后的byte数组
- *
- * @param n
- * short
- * @return byte[]
- */
- public static byte[] toLH(short n) {
- byte[] b = new byte[2];
- b[0] = (byte) (n & 0xff);
- b[1] = (byte) (n >> 8 & 0xff);
- return b;
- }
- /**
- * 将short转为高字节在前,低字节在后的byte数组
- *
- * @param n
- * short
- * @return byte[]
- */
- public static byte[] toHH(short n) {
- byte[] b = new byte[2];
- b[1] = (byte) (n & 0xff);
- b[0] = (byte) (n >> 8 & 0xff);
- return b;
- }
- /**
- * 将将int转为高字节在前,低字节在后的byte数组 public static byte[] toHH(int number) { int
- * temp = number; byte[] b = new byte[4]; for (int i = b.length - 1; i > -1;
- * i--) { b = new Integer(temp & 0xff).byteValue(); temp = temp >> 8; }
- * return b; } public static byte[] IntToByteArray(int i) { byte[] abyte0 =
- * new byte[4]; abyte0[3] = (byte) (0xff & i); abyte0[2] = (byte) ((0xff00 &
- * i) >> 8); abyte0[1] = (byte) ((0xff0000 & i) >> 16); abyte0[0] = (byte)
- * ((0xff000000 & i) >> 24); return abyte0; }
- */
- /**
- * 将float转为低字节在前,高字节在后的byte数组
- */
- public static byte[] toLH(float f) {
- return toLH(Float.floatToRawIntBits(f));
- }
- /**
- * 将float转为高字节在前,低字节在后的byte数组
- */
- public static byte[] toHH(float f) {
- return toHH(Float.floatToRawIntBits(f));
- }
- /**
- * 将String转为byte数组
- */
- public static byte[] stringToBytes(String s, int length) {
- while (s.getBytes().length < length) {
- s += " ";
- }
- return s.getBytes();
- }
- /**
- * 将字节数组转换为String
- *
- * @param b
- * byte[]
- * @return String
- */
- public static String bytesToString(byte[] b) {
- StringBuffer result = new StringBuffer("");
- int length = b.length;
- for (int i = 0; i < length; i++) {
- result.append((char) (b[i] & 0xff));
- }
- return result.toString();
- }
- /**
- * 将字符串转换为byte数组
- *
- * @param s
- * String
- * @return byte[]
- */
- public static byte[] stringToBytes(String s) {
- return s.getBytes();
- }
- /**
- * 将高字节数组转换为int
- *
- * @param b
- * byte[]
- * @return int
- */
- public static int hBytesToInt(byte[] b) {
- int s = 0;
- for (int i = 0; i < 3; i++) {
- if (b[i] >= 0) {
- s = s + b[i];
- } else {
- s = s + 256 + b[i];
- }
- s = s * 256;
- }
- if (b[3] >= 0) {
- s = s + b[3];
- } else {
- s = s + 256 + b[3];
- }
- return s;
- }
- /**
- * 将低字节数组转换为int
- *
- * @param b
- * byte[]
- * @return int
- */
- public static int lBytesToInt(byte[] b) {
- int s = 0;
- for (int i = 0; i < 3; i++) {
- if (b[3 - i] >= 0) {
- s = s + b[3 - i];
- } else {
- s = s + 256 + b[3 - i];
- }
- s = s * 256;
- }
- if (b[0] >= 0) {
- s = s + b[0];
- } else {
- s = s + 256 + b[0];
- }
- return s;
- }
- /**
- * 高字节数组到short的转换
- *
- * @param b
- * byte[]
- * @return short
- */
- public static short hBytesToShort(byte[] b) {
- int s = 0;
- if (b[0] >= 0) {
- s = s + b[0];
- } else {
- s = s + 256 + b[0];
- }
- s = s * 256;
- if (b[1] >= 0) {
- s = s + b[1];
- } else {
- s = s + 256 + b[1];
- }
- short result = (short) s;
- return result;
- }
- /**
- * 低字节数组到short的转换
- *
- * @param b
- * byte[]
- * @return short
- */
- public static short lBytesToShort(byte[] b) {
- int s = 0;
- if (b[1] >= 0) {
- s = s + b[1];
- } else {
- s = s + 256 + b[1];
- }
- s = s * 256;
- if (b[0] >= 0) {
- s = s + b[0];
- } else {
- s = s + 256 + b[0];
- }
- short result = (short) s;
- return result;
- }
- /**
- * 高字节数组转换为float
- *
- * @param b
- * byte[]
- * @return float
- */
- public static float hBytesToFloat(byte[] b) {
- int i = 0;
- Float F = new Float(0.0);
- i = ((((b[0] & 0xff) << 8 | (b[1] & 0xff)) << 8) | (b[2] & 0xff)) << 8 | (b[3] & 0xff);
- return F.intBitsToFloat(i);
- }
- /**
- * 低字节数组转换为float
- *
- * @param b
- * byte[]
- * @return float
- */
- public static float lBytesToFloat(byte[] b) {
- int i = 0;
- Float F = new Float(0.0);
- i = ((((b[3] & 0xff) << 8 | (b[2] & 0xff)) << 8) | (b[1] & 0xff)) << 8 | (b[0] & 0xff);
- return F.intBitsToFloat(i);
- }
- /**
- * 将byte数组中的元素倒序排列
- */
- public static byte[] bytesReverseOrder(byte[] b) {
- int length = b.length;
- byte[] result = new byte[length];
- for (int i = 0; i < length; i++) {
- result[length - i - 1] = b[i];
- }
- return result;
- }
- /**
- * 打印byte数组
- */
- public static void printBytes(byte[] bb) {
- int length = bb.length;
- for (int i = 0; i < length; i++) {
- System.out.print(bb + " ");
- }
- System.out.println("");
- }
- public static void logBytes(byte[] bb) {
- int length = bb.length;
- String out = "";
- for (int i = 0; i < length; i++) {
- out = out + bb + " ";
- }
- }
- /**
- * 将int类型的值转换为字节序颠倒过来对应的int值
- *
- * @param i
- * int
- * @return int
- */
- public static int reverseInt(int i) {
- int result = FormatTransfer.hBytesToInt(FormatTransfer.toLH(i));
- return result;
- }
- /**
- * 将short类型的值转换为字节序颠倒过来对应的short值
- *
- * @param s
- * short
- * @return short
- */
- public static short reverseShort(short s) {
- short result = FormatTransfer.hBytesToShort(FormatTransfer.toLH(s));
- return result;
- }
- /**
- * 将float类型的值转换为字节序颠倒过来对应的float值
- *
- * @param f
- * float
- * @return float
- */
- public static float reverseFloat(float f) {
- float result = FormatTransfer.hBytesToFloat(FormatTransfer.toLH(f));
- return result;
- }
- }
ByteBuffer类中的order(ByteOrder bo) 方法可以设置 ByteBuffer 的字节序。
其中的ByteOrder是枚举:
ByteOrder BIG_ENDIAN 代表大字节序的 ByteOrder 。
ByteOrder LITTLE_ENDIAN 代表小字节序的 ByteOrder 。
ByteOrder nativeOrder() 返回当前硬件平台的字节序。
发表评论
-
【转】Java开发必会的Linux命令
2016-01-14 18:16 1107作为一个Java开发人员,有些常用的Linux命令必须掌 ... -
深入理解并发之CompareAndSet(CAS)
2016-01-08 16:20 12820一、CAS简介 CAS:Compare and Swap, ... -
Scala学习笔记(一)
2015-12-21 14:07 1933一、变量 获取变量的 ... -
跟我学Dubbo系列之Java SPI机制简介
2015-11-22 10:34 2375SPI 简介 SPI 全称为 (Service Provi ... -
跟我学系列之趣解NIO和IO的区别
2015-11-12 21:46 729在上一次分享中,咱们谈到了阻塞与非阻塞,同步与异步的区别, ... -
同步,异步,阻塞和非阻塞的区别
2015-11-11 17:54 1243一、概念 异步:某个事情需要10s完成。而我只需要调用某 ... -
跟我学系列之JVM远程性能监控
2015-10-24 22:14 887新写的文章在这里: http://www. ... -
【转】使用 VisualVM 进行性能分析及调优
2015-10-11 18:10 759概述 开发大型 Java 应用程序的过程中难免遇到内存泄 ... -
【转】支持生产阻塞的线程池
2015-07-21 10:31 2在网上看到一篇文章写的非常不错,忍不住转发。 原文如下: ... -
一段JAVA线程池的设置引发的血案
2015-07-18 17:59 3237应公司需求我 ... -
GC日志分析
2015-07-10 14:14 841JVM的GC日志的主要参数包括如下几个: -XX:+Pri ... -
【转】Java常见内存溢出异常分析
2015-07-10 14:11 1691Java虚拟机规范规定JVM的内存分为了好几块,比如堆,栈, ... -
线程池在任何场景下都比顺序执行快吗??
2015-06-30 17:32 1485有时候并不是在任何场景下使用线程池,效率都比顺序执行程序快, ... -
由不断的创建线程产生的内存错误所想到的
2015-05-06 13:20 1234public class MultiThreadOOM { ... -
跟我学系列之Netty源码图
2015-04-30 13:28 936客户端结构: 服务端结构: -
跟我学系列之NIO的那些坑
2015-04-30 10:06 2024public class EchoServer { ... -
临时记录
2015-04-09 15:49 618mvn deploy -Dmaven.test.skip= ... -
单例模式与垃圾回收
2015-04-07 15:57 828讨论命题:当一个单例的对象长久不用时,会不会被jvm的垃圾收 ... -
使用Eclipse MAT查找内存泄漏工具介绍
2015-03-14 11:27 1424一、MAT是什么? ... -
【转】MAT(Memory Analyzer Tool)工具入门介绍
2015-03-14 11:18 11、MAT是什么? MAT(Memory Anal ...
相关推荐
STM32F103通常是小端字节序,但如果你需要在不同字节序的系统间交换数据,可能需要进行字节序转换,例如使用`ntohl`(网络字节序到主机字节序)和`htonl`(主机字节序到网络字节序)函数。 以上就是关于STM32F103上...
字节序分为大端字节序(Big-Endian)和小端字节序(Little-Endian)。大端字节序是指最高位(最显著的位)的字节位于最低地址,而小端字节序则相反,最低位的字节位于最低地址。 在`intToBytes`方法中,我们看到的...
在这个"034 gbk_utf_ansi_asc字符集分析字节序"的压缩包中,很可能是提供了关于这些编码格式的详细分析,包括它们的字节表示、转换过程和可能遇到的问题。分析这些内容有助于深入理解字符编码的原理,从而在实际开发...
因此,在进行跨平台数据交换时,需要考虑字节序问题,确保正确解读4字节数值。 总的来说,浮点数与4字节数值的转换涉及到对二进制表示的理解,包括符号、指数和尾数的处理,以及可能的字节顺序问题。通过掌握这些...
根据描述,我们主要讨论两种字节序:小端字节序(Little Endian)和大端字节序(Big Endian),这两种字节序在不同的处理器架构中有不同的应用。 #### 小端字节序(Little Endian) 小端字节序的特点是将低字节存储...
这里我们主要讨论两种字节顺序:大端字节序(Big-endian)和小端字节序(Little-endian)。这两个术语源自Gulliver's Travels中的两个部落名称,用来形象地描述数据在内存中的排列方式。 标题“Little_Big_endian....
"swap_io.rar_swap"这个标题暗示了我们正在讨论与字节交换相关的操作,可能是一个用于处理字节序转换的库或者工具。描述中的“大小字节转换”进一步明确了这一点,它指的是在大端字节序(Big-Endian)和小端字节序...
描述中的信息进一步确认了这一点,它提到告诉"sys endian.h"我们有MD变种的交换宏,这表明我们在讨论的是关于计算机体系结构中字节序处理的问题。 在计算机科学中,字节序是内存中多字节数值的字节排列顺序。有两种...
这种转换通常涉及对数据类型的字段进行逐个读取或写入,以及可能的字节序处理(如大端序和小端序)。 在易语言中,实现这样的转换可以使用各种内置函数和命令。例如,可以使用“结构到字节集”命令将自定义数据类型...
描述中提到的"ARM supports little-endian and big-endian for linux Device Driver"进一步确认了我们在讨论ARM处理器在Linux设备驱动程序中的字节序支持。 首先,让我们来理解一下字节序。字节序是指多字节数据...
2. 数据存储格式:解释如何组织和编码多字节数据,例如采用大端或小端字节序来存储多字节数值。 3. 单字节操作:介绍如何向EEPROM写入一个字节,并读取该字节的方法,通常涉及I/O操作和特定的编程API。 4. 多字节...
3. 在转换过程中,可能会遇到字节顺序问题,特别是在处理网络字节序和本地字节序时。在Android中,通常不需要担心这个问题,因为byte数组通常不涉及字节序。 总结,Android中将字节数组转换为十六进制字符串的方法...
这个工具可能是程序员、网络开发者或者数据处理人员使用的,帮助他们处理二进制数据,进行不同编码间的转换,例如ASCII到UTF-8,或者其他特定的字节序转换,如大端序到小端序。 标签“字节转换请求工具共11页.pdf”...
在网络通信中,为了确保不同字节序的计算机间能够正确交换数据,TCP/IP协议定义了一种标准的字节序,即网络字节序,它采用大端字节序。例如,16位的端口号1000(0x3e8)在网络传输时,应当按照0x03(低地址)和0xe8...
同时,注意在进行这种低级操作时,确保数据类型匹配和大小端问题,因为不同的系统可能使用不同的字节序。在必要的时候,还需要进行字节序转换(如大端转小端,小端转大端)以确保数据正确解读。 总的来说,4字节...
标题中的"speex_header.rar_little_speex"暗示了我们正在处理与Speex音频编码相关的文件,特别是关于处理小端字节序的头文件。Speex是一种免费的、开源的、可扩展的音频编解码器,专为语音通信优化,尤其是在网络...
例如,它可能会讨论TCP/IP协议栈如何处理字节序,或者在Java编程语言中如何使用`java.nio.ByteOrder`类来处理字节序。 总之,Endian是计算机科学中一个基础但至关重要的概念,理解它对于进行系统设计、网络编程和...
1. `ntohs(u_short)` 和 `htons(u_short)`:这两个函数分别用于将16位的网络字节序转换为主机字节序,以及将16位的主机字节序转换为网络字节序。`ntohs` 是 "Network to Host Short" 的缩写,`htons` 是 "Host to ...
网络字节序,也称为网络标准字节序,是TCP/IP协议规定的一种统一的字节序,即大端字节序。当不同平台的计算机进行网络通信时,为了保证数据的一致性,必须将本地的数据转换成网络字节序进行传输,接收方再将其转换回...