- 浏览: 163619 次
- 来自: ...
-
文章分类
- 全部博客 (110)
- 网络 (3)
- window (1)
- eclipse (2)
- mysql (3)
- java (43)
- spring (2)
- memcahe (4)
- kestrel (1)
- linux (19)
- maven (1)
- 总结 (1)
- ActiveMQ (1)
- 线程 (6)
- nio (7)
- java pool (1)
- IO (1)
- 架构 (1)
- Hadoop (1)
- Storm (1)
- zookeeper (3)
- 工作进程 (1)
- epoll (3)
- nginx (4)
- uml (1)
- 分布式 (1)
- RMI (4)
- redis (1)
- shell (4)
- 黄金文档 (1)
- office (2)
- linux_setup (1)
- visio (1)
- BIOS (1)
- 回调 (1)
- jvm (1)
- resin (1)
- ssd (0)
- xmpp (1)
最新评论
-
qxjandyc:
hjjjjjjjjjjjjjjjjjjjjjj
(emoji表情) unicode5与unicode6互换 -
一个人旅行:
写的不错哦
(emoji表情) unicode5与unicode6互换
http://blog.csdn.net/cyh1111/article/details/5129976
以下对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中提供了四个转换字节序的宏。
/** * 通信格式转换 * * 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 & 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 >= 0) { s = s + b; } else { s = s + 256 + b; } 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; } 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; } }
发表评论
-
java final关键字
2012-10-21 21:20 1065Java中的final关键字通常的指的是“这是无法改变的”。它 ... -
Java:List中的toArray()的使用方法
2012-10-16 17:15 1074http://webservices.ctocio.com.c ... -
jvm 参数设置 -D
2012-10-16 14:06 9611、log4j 配置文件 -Dlog4j.configurat ... -
Java核心技术(第8版) – 读书笔记
2012-09-03 15:15 801http://www.coder4.com/archives/ ... -
线程123总结
2012-09-02 22:34 778线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一 ... -
Arraylist与linkedlist的区别
2012-08-31 16:44 787List: 有顺序的,元素可以重复 遍历:for 迭代 排 ... -
Java RMI之HelloWorld篇
2012-08-29 11:53 594http://www.cnblogs.com/ninahan0 ... -
Comparator和Comparable在排序中 区别
2012-08-21 09:40 756当需要排序的集合或数组不是单纯的数字类型的时候,通常可以使用C ... -
Spring Bean相关的接口、aware接口、FactoryBean
2012-08-02 14:57 37401、 package spring.beansandcon ... -
关系 UML 说明
2012-08-01 22:56 789关联是类之间的一种关系,例如老师教学生,老公和老婆,水壶装水等 ... -
replace和replaceAll 区别
2012-08-01 14:59 820replace和replaceAll是JAVA中常用的替换字符 ... -
JAVA ANNOTATION详解
2012-08-01 14:56 758http://www.cnblogs.com/phoebus0 ... -
Java中的Enum用法介绍
2012-07-27 09:39 991http://blog.sina.com.cn/s/blog_ ... -
获取本地ip
2012-07-26 09:09 908/** * @Title: getLocalIp ... -
动态代理
2012-07-25 10:29 728http://blog.csdn.net/cz_hyf/art ... -
NIO揭秘-1
2012-07-24 11:15 731http://my.oschina.net/zhangya/b ... -
FileChannel类的简单用法
2012-07-23 20:12 899http://blog.163.com/yf_198407/b ... -
JDK5.0 新特性
2012-07-23 17:30 7611.AutoBoxing 原来int是非Object,在JDK ... -
java jdk5 新特性 Annotation(注释)
2012-07-23 17:29 840http://www.iteye.com/topic/1653 ... -
java jdk5 新特性 可变参数
2012-07-23 17:28 703java jdk5 的新特性:可变参数 Java代码 ...
相关推荐
Java 网络字节序转换是编程过程中一个重要的概念,尤其在跨平台通信和处理二进制数据时。字节序是指多字节数据(如整数或浮点数)在内存或文件中存储的顺序。主要有两种字节序:Big-Endian(大端字节序)和 Little-...
Java中的默认字节序是网络字节序,也就是大端字节序。 2. **解析过程**:将16进制字符串转换为浮点数,通常涉及以下步骤: - 将16进制字符串转换为字节数组,每个字节对应一个16进制字符。 - 根据字节序调整字节...
二进制杂谈 1、十进制、二进制、十六进制 2、计算机储存单位 3、进制转换 4、有符号编码 5、反码的设计原理 6、二进制的位运算 7、位操作符 8、内存与内存地址 9、字节序 10、Java解码 11、Java编码
**字节序与Java字节序:** 字节序决定了多字节数据在内存中的存储顺序。Java使用**大端字节序**,即高位字节存储在低地址,低位字节存储在高地址。 **JDK与JRE的区别:** 1. **JDK**:包含JRE,提供Java开发工具,...
Java的`DataInputStream`和`DataOutputStream`类提供了处理基本数据类型(如int、float)的方法,并且在写入时会自动处理字节序(大端或小端)。而`ObjectInputStream`和`ObjectOutputStream`则用于序列化和反序列化...
需要注意的是,Java的标准字节序是大端字节序,但是这并不意味着所有的硬件平台都遵循这个标准。因此,在进行字节序转换时,尤其是在跨平台的环境中,我们需要特别注意字节序的问题,以确保数据的一致性和正确性。 ...
对于字节序转换,Java提供了`java.nio.ByteOrder`类,可以方便地在大端和小端之间切换。 PHP是另一种常用的Web开发语言,其文件操作主要通过`fopen`、`fwrite`和`fread`等函数完成。在网络字节流方面,PHP提供了`...
Java字节码指令集是Java虚拟机(JVM)执行程序的基础,它是Java源代码经过编译后的二进制表示形式。每个字节码指令都由一个操作码(Opcode)和可能的操作数组成,用于控制JVM执行各种操作。本文将深入探讨Java字节码...
字节序转换辅助类,short大小端转换,ushort大小端转换,int大小端转换,uint大小端转换,long大小端转换,ulong大小端转换; short类型 小端转大端,short类型 大端转小端,int类型 小端转大端,int类型 大端转小端...
因此,当Java(使用小端字节序)和C++(可能使用大端或小端,取决于硬件平台)进行通信时,需要进行字节序转换。 在C++中,结构体是一种自定义数据类型,可以包含不同类型的数据成员。为了通过Socket发送,需要将...
例如,在大端序中,最高位的字节在数组的最前面,而在小端序中,最高位的字节在数组的最后面。 在实际应用中,这些转换可能会涉及到更多的边界检查和错误处理,例如检查输入数组的长度是否符合要求,以及处理可能的...
"Java整型数与网络字节序byte[]数组转换关系详解" 本文主要介绍了Java整型数与网络字节序byte[]数组之间的转换关系,包括整型数到byte[]数组的转换和byte[]数组到整型数的转换。这些转换关系在Java和C/C++之间的...
本篇文章主要探讨了Java如何与C、C++、Delphi等Windows编程语言进行数据类型的转换,尤其是针对字节序(endianness)的问题。 字节序是指多字节数据类型(如int、float等)在内存中的存储顺序。主要有两种字节序:...
5. 大端字节序(bigendian)和小端字节序(littleendian):在计算机中,不同硬件平台可能会有不同的字节序表示法。JVM规范了字节码使用大端字节序,但当字节码运行在小端字节序的CPU上时,可能需要进行适当的转换。 6....
- **Java的字节序**:Java采用大端字节序,意味着在多字节数据中,高位字节存储在低地址处。 4. **JDK与JRE的区别**: - **JDK**:Java开发工具包,包含了Java编译器、调试器、文档生成工具等,用于开发和运行...
Java默认使用大端字节序,而BMP文件使用小端字节序存储数据。因此,读取BMP文件时,必须将读取到的数据进行字节序转换,才能正确解析文件内容。 例如,`constructInt`函数通过将四个字节重新排序来构建一个整数,以...
本主题聚焦于一个特定的工具或源码,即“16进制单精度(32位)浮点型转换器”,它能够将32位的浮点数在16进制表示与十进制表示之间进行转换,并考虑到了不同的字节序——大端和小端。 首先,我们要理解16进制和...
在传输前,需要将结构体数据转换为网络字节序,Java的`java.nio.ByteOrder`和C++的`htonl`, `ntohl`等函数可用来处理字节序问题。 5. **跨语言通信的库和框架**: - **JNI(Java Native Interface)**:Java提供...
这将生成一个名为`HelloWorldApp.class`的字节码文件。然后,通过`java`命令来运行程序: ```sh java HelloWorldApp ``` 如果一切正常,控制台会输出“Hello World!”。 #### 5. Applet概述与实现 Applet是一种...
4. 平台兼容性:由于Java和C语言的字节序不同,可能需要在数据传输前进行字节序转换。例如,Java是大端序,而大多数C编译器默认为小端序。可以使用`java.nio.ByteBuffer`的`order()`方法在Java端设置字节序,C语言端...