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进行解释具体数据是多少?你们自己去计算并比较吧!
===============================================================================================
/** * 通信格式转换 * * 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 < 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