精华内容
下载资源
问答
  • 字节序分大端字节序和小端字节序。 大端字节序(big-endian)与小端字节序(little-endian)的区别如图: 把给定系统使用的字节序称为主机字节序,网络协议使用的字节序称为网络字节序网络字节序是大端字节序,而...

    字节序分大端字节序和小端字节序。
    大端字节序(big-endian)与小端字节序(little-endian)的区别如图:
    图来自unix网络编程
    把给定系统使用的字节序称为主机字节序,网络协议使用的字节序称为网络字节序。网络字节序是大端字节序,而主机字节序由系统决定,因此,两者间需要转化后才能使用,有以下几个转换函数:
    图片来自unix网络编程
    函数名中h->host; n->network; s->short; l->long;

    展开全文
  • 该文主要说说网络字节序和主机字节序区别以及Little endian与Big endian的概念。其实编程的事就比较简单了我也懒得写了,直接引用了我觉得写的挺好的两篇文章:来源:http://blog.ednchina.com/qi...

    最近在项目开发过程中,需要在采用JAVA作为语言的服务器与采用C++作为语言的服务器间进行通信,这就涉及到这两种语言间数据类型的转换以及网络字节序与主机字节序的区别。该文主要说说网络字节序和主机字节序的区别以及Little endian与Big endian的概念。其实编程的事就比较简单了

    我也懒得写了,直接引用了我觉得写的挺好的两篇文章:

    来源:http://blog.ednchina.com/qinyonglyz/194674/message.aspx

    1.故事的起源

    “endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。

    我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。

    2.什么是Big Endian和Little Endian?

    在设计计算机系统的时候,有两种处理内存中数据的方法。一种叫为little-endian,存放在内存中最低位的数值是来自数据的最右边部分(也就是数据的最低位部分)。比如一个16进制数字0x12345678,在内存存放的方式如下:

    0111,1000

    0101,0110

    0011,0100

    0001,0010

    地址

    100

    101

    102

    103

    另一种称为big-endian,正好相反,存放在内存中最低位的数值是来自数据的最左边边部分(也就是数据的最高为部分)。比如一个16进制数字0x12345678,在内存存放的方式如下:

    0001,0010

    0011,0100

    0101,0110

    0111,1000

    地址

    100

    101

    102

    103

    比如某些文件需要在不同平台处理,或者通过Socket通信。这方面我们可以借助ntohl(), ntohs(), htonl(), and htons()函数进行格式转换。

    3.如何判断系统是Big Endian还是Little Endian?

    在/usr/include/中(包括子目录)查找字符串BYTE_ORDER(或_BYTE_ORDER, __BYTE_ORDER),确定其值。这个值一般在endian.h或machine/endian.h文件中可以找到,有时在feature.h中,不同的操作系统可能有所不同。一般来说,Little Endian系统BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER)为1234,Big Endian系统为4321。大部分用户的操作系统(如windows, FreeBsd,Linux)是Little Endian的。少部分,如MAC OS ,是Big Endian 的。本质上说,Little Endian还是Big Endian与操作系统和芯片类型都有关系。

    ======================================================================

    ext3 文件系统在硬盘分区上的数据是按照 Intel 的 Little-endian 格式存放的,如果是在 PC 以外的平台上开发 ext3 相关的程序,要特别注意这一点。

    谈到字节序的问题,必然牵涉到两大 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方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。

    来源:http://www.cnblogs.com/jacktu/archive/2008/11/24/1339789.html

    不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序

    最常见的有两种

    1. Little endian:将低序字节存储在起始地址

    2. Big endian:将高序字节存储在起始地址

    LE little-endian

    最符合人的思维的字节序

    地址低位存储值的低位

    地址高位存储值的高位

    怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说

    低位值小,就应该放在内存地址小的地方,也即内存地址低位

    反之,高位值就应该放在内存地址大的地方,也即内存地址高位

    BE big-endian

    最直观的字节序

    地址低位存储值的高位

    地址高位存储值的低位

    为什么说直观,不要考虑对应关系

    只需要把内存地址从左到右按照由低到高的顺序写出

    把值按照通常的高位到低位的顺序写出

    两者对照,一个字节一个字节的填充进去

    例子:在内存中双字0x01020304(DWORD)的存储方式

    内存地址

    4000 4001 4002 4003

    LE 04 03 02 01

    BE 01 02 03 04

    例子:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为

    big-endian  little-endian

    0x0000  0x12      0xcd

    0x0001  0x23      0xab

    0x0002  0xab      0x34

    0x0003  0xcd      0x12

    x86系列CPU都是little-endian的字节序.

    网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。

    为了进行转换 bsd socket提供了转换的函数 有下面四个

    htons 把unsigned short类型从主机序转换到网络序

    htonl 把unsigned long类型从主机序转换到网络序

    ntohs 把unsigned short类型从网络序转换到主机序

    ntohl 把unsigned long类型从网络序转换到主机序

    在使用little endian的系统中 这些函数会把字节序进行转换

    在使用big endian类型的系统中 这些函数会定义成空宏

    同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序 不然两方的解释不一样就会产生bug.

    注:

    1、网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)

    2、不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。

    处理器    操作系统    字节排序

    Alpha    全部    Little endian

    HP-PA    NT    Little endian

    HP-PA    UNIX    Big endian

    Intelx86    全部    Little endian

    Motorola680x()    全部    Big endian

    MIPS    NT    Little endian

    MIPS    UNIX    Big endian

    PowerPC    NT    Little endian

    PowerPC    非NT    Big endian  

    RS/6000    UNIX    Big endian

    SPARC    UNIX    Big endian

    IXP1200 ARM核心    全部    Little 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

    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

    result[length-i-1] = b;

    }

    return result;

    }

    /**

    * 打印byte数组

    */

    public static void printBytes(byte[] bb) {

    int length = bb.length;

    for (int i=0; i

    System.out.print(bb + " ");

    }

    System.out.println("");

    }

    public static void logBytes(byte[] bb) {

    int length = bb.length;

    String ut = "";

    for (int i=0; i

    ut = 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;

    }

    }

    展开全文
  • 网络字节序主机字节序有什么区别,这是我16年9月份校招面试腾讯被问到的一个问题,也是Linux服务器开发岗常考的面试题。 字节序分为大端字节序和小端字节序 大端字节序是指一个整数的高位字节(32-31bit)...

    网络字节序跟主机字节序有什么区别,这是我16年9月份校招面试腾讯被问到的一个问题,也是Linux服务器开发岗常考的面试题。

    字节序分为大端字节序和小端字节序

    • 大端字节序是指一个整数的高位字节(32-31bit)存储在内存的低地址处,低位字节(0-7bit)存储在内存的高地址处。
    • 小端字节序是指一个整数的高位字节(32-31bit)存储在内存的高地址处,低位字节(0-7bit)存储在内存的低地址处。

    现代PC大多采用小端字节序,所以小端字节序又被称为主机字节序。
    大端字节序也称为网络字节序。

    即使是同一台机器上的两个进程(比如一个由C语言,另一个由Java编写)通信,也要考虑字节序的问题(JVM采用大端字节序)。

    可编写 byteorder.cpp 判断机器字节序

    void byteorder()
    {
    	union
    	{
    		short value;
    		char union_bytes[sizeof(short)];
    	}test;
    	test.value = 0x0102;
    
    	if (sizeof(short) == 2)
    	{
    		if (test.union_bytes[0] == 1 && test.union_bytes[1] == 2)
    			cout << "big endian" << endl;
    		else if (test.union_bytes[0] == 2 && test.union_bytes[1] == 1)
    			cout << "little endian" << endl;
    		else
    			cout << "unknown" << endl;
    	}
    	else
    	{
    		cout << "sizeof(short) == " << sizeof(short) << endl;
    	}
    
    	return ;
    }
    

    该程序在我的ubuntu跟win10下执行结果都是 little endian

    展开全文
  • 该文主要说说网络字节序和主机字节序区别以及Little endian与Big endian的概念。其实编程的事就比较简单了我也懒得写了,直接引用了我觉得写的挺好的两篇文章:来源:http://blog.ednchina.com/qi...

    最近在项目开发过程中,需要在采用JAVA作为语言的服务器与采用C++作为语言的服务器间进行通信,这就涉及到这两种语言间数据类型的转换以及网络字节序与主机字节序的区别。该文主要说说网络字节序和主机字节序的区别以及Little endian与Big endian的概念。其实编程的事就比较简单了

    我也懒得写了,直接引用了我觉得写的挺好的两篇文章:

    来源:http://blog.ednchina.com/qinyonglyz/194674/message.aspx

    1.故事的起源

    “endian”这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开,由此曾发生过六次叛乱,其中一个皇帝送了命,另一个丢了王位。

    我们一般将endian翻译成“字节序”,将big endian和little endian称作“大尾”和“小尾”。

    2.什么是Big Endian和Little Endian?

    在设计计算机系统的时候,有两种处理内存中数据的方法。一种叫为little-endian,存放在内存中最低位的数值是来自数据的最右边部分(也就是数据的最低位部分)。比如一个16进制数字0x12345678,在内存存放的方式如下:

    0111,1000

    0101,0110

    0011,0100

    0001,0010

    地址

    100

    101

    102

    103

    另一种称为big-endian,正好相反,存放在内存中最低位的数值是来自数据的最左边边部分(也就是数据的最高为部分)。比如一个16进制数字0x12345678,在内存存放的方式如下:

    0001,0010

    0011,0100

    0101,0110

    0111,1000

    地址

    100

    101

    102

    103

    比如某些文件需要在不同平台处理,或者通过Socket通信。这方面我们可以借助ntohl(), ntohs(), htonl(), and htons()函数进行格式转换。

    3.如何判断系统是Big Endian还是Little Endian?

    在/usr/include/中(包括子目录)查找字符串BYTE_ORDER(或_BYTE_ORDER, __BYTE_ORDER),确定其值。这个值一般在endian.h或machine/endian.h文件中可以找到,有时在feature.h中,不同的操作系统可能有所不同。一般来说,Little Endian系统BYTE_ORDER(或_BYTE_ORDER,__BYTE_ORDER)为1234,Big Endian系统为4321。大部分用户的操作系统(如windows, FreeBsd,Linux)是Little Endian的。少部分,如MAC OS ,是Big Endian 的。本质上说,Little Endian还是Big Endian与操作系统和芯片类型都有关系。

    ======================================================================

    ext3 文件系统在硬盘分区上的数据是按照 Intel 的 Little-endian 格式存放的,如果是在 PC 以外的平台上开发 ext3 相关的程序,要特别注意这一点。

    谈到字节序的问题,必然牵涉到两大 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方式称之为网络字节序。当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。

    来源:http://www.cnblogs.com/jacktu/archive/2008/11/24/1339789.html

    不同的CPU有不同的字节序类型 这些字节序是指整数在内存中保存的顺序 这个叫做主机序

    最常见的有两种

    1. Little endian:将低序字节存储在起始地址

    2. Big endian:将高序字节存储在起始地址

    LE little-endian

    最符合人的思维的字节序

    地址低位存储值的低位

    地址高位存储值的高位

    怎么讲是最符合人的思维的字节序,是因为从人的第一观感来说

    低位值小,就应该放在内存地址小的地方,也即内存地址低位

    反之,高位值就应该放在内存地址大的地方,也即内存地址高位

    BE big-endian

    最直观的字节序

    地址低位存储值的高位

    地址高位存储值的低位

    为什么说直观,不要考虑对应关系

    只需要把内存地址从左到右按照由低到高的顺序写出

    把值按照通常的高位到低位的顺序写出

    两者对照,一个字节一个字节的填充进去

    例子:在内存中双字0x01020304(DWORD)的存储方式

    内存地址

    4000 4001 4002 4003

    LE 04 03 02 01

    BE 01 02 03 04

    例子:如果我们将0x1234abcd写入到以0x0000开始的内存中,则结果为

    big-endian  little-endian

    0x0000  0x12      0xcd

    0x0001  0x23      0xab

    0x0002  0xab      0x34

    0x0003  0xcd      0x12

    x86系列CPU都是little-endian的字节序.

    网络字节顺序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节顺序采用big endian排序方式。

    为了进行转换 bsd socket提供了转换的函数 有下面四个

    htons 把unsigned short类型从主机序转换到网络序

    htonl 把unsigned long类型从主机序转换到网络序

    ntohs 把unsigned short类型从网络序转换到主机序

    ntohl 把unsigned long类型从网络序转换到主机序

    在使用little endian的系统中 这些函数会把字节序进行转换

    在使用big endian类型的系统中 这些函数会定义成空宏

    同样 在网络程序开发时 或是跨平台开发时 也应该注意保证只用一种字节序 不然两方的解释不一样就会产生bug.

    注:

    1、网络与主机字节转换函数:htons ntohs htonl ntohl (s 就是short l是long h是host n是network)

    2、不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。

    处理器    操作系统    字节排序

    Alpha    全部    Little endian

    HP-PA    NT    Little endian

    HP-PA    UNIX    Big endian

    Intelx86    全部    Little endian

    Motorola680x()    全部    Big endian

    MIPS    NT    Little endian

    MIPS    UNIX    Big endian

    PowerPC    NT    Little endian

    PowerPC    非NT    Big endian  

    RS/6000    UNIX    Big endian

    SPARC    UNIX    Big endian

    IXP1200 ARM核心    全部    Little 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

    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

    result[length-i-1] = b;

    }

    return result;

    }

    /**

    * 打印byte数组

    */

    public static void printBytes(byte[] bb) {

    int length = bb.length;

    for (int i=0; i

    System.out.print(bb + " ");

    }

    System.out.println("");

    }

    public static void logBytes(byte[] bb) {

    int length = bb.length;

    String ut = "";

    for (int i=0; i

    ut = 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;

    }

    }

    展开全文
  • 该文主要说说网络字节序和主机字节序区别以及Little endian与Big endian的概念。其实编程的事就比较简单了我也懒得写了,直接引用了我觉得写的挺好的两篇文章:来源:http://blog.ednchina.com/qi...
  • 最近在项目开发过程中,需要在采用JAVA作为语言的服务器与采用C++作为语言的服务器间进行通信,这就涉及到这两种语言间数据类型...该文主要说说网络字节序和主机字节序区别以及Little endian与Big endian的
  • 该文主要说说网络字节序和主机字节序区别以及Little endian与Big endian的概念。其实编程的事就比较简单了 我也懒得写了,直接引用了我觉得写的挺好的两篇文章: 什么是Big Endian和Little Endi...
  • 网络字节序 主机字节序 区别

    千次阅读 2009-08-19 12:24:00
    http://www.cnblogs.com/wqlblogger/archive/2008/01/25/1052915.html一、字节序定义字节序,...其实大部分人在实际的开发中都很少会直接和字节序打交道。唯有在跨平台以及网络程序中字节序才是一个应该被考虑的问题。
  • /*将32位的长整数从网络字节序转换为主机字节序,*/ uint32_t ntohl(uint32_t netlong); /*将16位的短整数从网络字节序转换为主机字节序,*/ uint16_t ntohs(uint16_t netshort); 这样记忆,h代表host...
  • 该文主要说说网络字节序和主机字节序区别以及Little endian与Big endian的概念。其实编程的事就比较简单了 我也懒得写了,直接引用了我觉得写的挺好的两篇文章: 什么是Big Endian和Little Endi...
  • 所谓网络字节序问题,主要是网络存储和主机存储的区别。网络存储是大端存储,而主机是小端存储。 主机端的小端存储转为网络字节序,用的函数:uint16_t htons(uint16_t hostshort); uint32_t htonl(uint32_t host...
  • 该文主要说说网络字节序和主机字节序区别以及Little endian与Big endian的概念。其实编程的事就比较简单了 我也懒得写了,直接引用了我觉得写的挺好的两篇文章:什么是Big Endian和Little Endia

空空如也

空空如也

1 2 3 4 5
收藏数 99
精华内容 39
关键字:

网络字节序和主机字节序区别