zoukankan      html  css  js  c++  java
  • 主机字节序 与 网络字节序

    一、字节顺序

    是指占用内存多于一个字节类型的数据在内存中的存放顺序。


    计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。

    但是,网络传输、文件储存、人类读写习惯使用大端字节序。

      java中一个int型数据占用4个字节,假如有一个16进制的int数,int value =(高字节) 0x01020304 (低字节)

    小端字节序(little endian):低字节数据存放在内存低地址

    大端字节序(bigendian): 低字节数据存放在高地址处

    主机字节序跟CPU有关的,IA架构(Intel、AMD)的CPU中是Little-Endian

    所谓的JAVA字节序指的是在JAVA虚拟机中多字节类型数据的存放顺序,JAVA字节序也是BIG-ENDIAN。

    由于JVM会根据底层的操作系统和CPU自动进行字节序的转换,

    所以我们使用java进行网络编程,几乎感觉不到字节序的存在。

      

    二、ByteBuffer 示例

    public static void byteOrder() {
    
            int x = 0x01020304;
    
            ByteBuffer bb = ByteBuffer.wrap(new byte[4]);
            bb.asIntBuffer().put(x);
            System.out.println( bb.order() +  " 内存数据 " +  Arrays.toString(bb.array()));
    
            bb.order(ByteOrder.LITTLE_ENDIAN);
            bb.asIntBuffer().put(x);
            System.out.println( bb.order() +    " 内存数据 " +  Arrays.toString(bb.array()));
        }

    BIG_ENDIAN 内存数据 [1, 2, 3, 4]
    LITTLE_ENDIAN 内存数据 [4, 3, 2, 1]

    三、Java 与 JavaScript 字节转换

    如果通信的双方都是Java,则根本不用考虑字节序的问题了。 

    Java 的 byte 范围是[-128, 127],

    JavaScript 的 byte 范围是[0, 256]

    四、int 与 byte Array 转换示例

    转换时使用相同的字节序

        // 生成4个字节的网络字节序,网络传输使用大端字节序,相当于int2ByteArray
        byte[] getNetworkBytesOrder(int sourceNumber) {
            byte[] orderBytes = new byte[4];
            orderBytes[3] = (byte) (sourceNumber & 0xFF);
            orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF);
            orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF);
            orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF);
            return orderBytes;
        }
    
        // 还原4个字节的网络字节序, 相当于byteArray2Int
        int recoverNetworkBytesOrder(byte[] orderBytes) {
            int sourceNumber = 0;
            for (int i = 0; i < 4; i++) {
                sourceNumber <<= 8;
                sourceNumber |= orderBytes[i] & 0xff;
            }
            return sourceNumber;
        }

            System.out.println(Arrays.toString(intToByteArray(32)));
            System.out.println(Arrays.toString(intToByteArray(145)));
            System.out.println(Arrays.toString(intToByteArray(256)));
    
            System.out.println(Arrays.toString(intToByteArray2(32)));
            System.out.println(Arrays.toString(intToByteArray2(145)));
            System.out.println(Arrays.toString(intToByteArray2(256)));
           
            //还原
            System.out.println(byteArrayToInt2(intToByteArray2(145)));
            System.out.println(byteArrayToInt(intToByteArray2(145)));

    输出

    [0, 0, 0, 32]
    [0, 0, 0, -111]
    [0, 0, 1, 0]
    [0, 0, 0, 32]
    [0, 0, 0, -111]
    [0, 0, 1, 0]
    145
    145

        public static byte[] intToByteArray(int i) {
            byte[] result = new byte[4];
            result[0] = (byte)((i >> 24) & 0xFF);
            result[1] = (byte)((i >> 16) & 0xFF);
            result[2] = (byte)((i >> 8) & 0xFF);
            result[3] = (byte)(i & 0xFF);
            return result;
        }
    
        public static byte[] intToByteArray2(int i) {
            return ByteBuffer
                    .allocate(4)
    //                默认大端字节序
    //                .order(ByteOrder.LITTLE_ENDIAN)
                    .putInt(i)
                    .array();
        }
    
    
        public static int byteArrayToInt2(byte[] byteArray) {
            int value = 0;
            for (int i = 0; i < 4; i++) {
                int shift = (4 - 1 - i) * 8;
                value += (byteArray[i] & 0x000000FF) << shift;
            }
            return value;
        }
    
        public static int byteArrayToInt(byte [] byteArray){
            return ByteBuffer.wrap(byteArray)
    //                默认大端字节序
    //                .order(ByteOrder.LITTLE_ENDIAN)
                    .getInt();
        }
  • 相关阅读:
    BEGIN2 序列求和
    BEGIN2 序列求和
    《算法竞赛入门经典》 习题45 IP网络(IP Networks,ACM、ICPC NEERC 2005,UVa1590)
    C#中char空值的几种表示方式
    C#中char空值的几种表示方式
    C#中() =>是什么意思
    C#中() =>是什么意思
    C# Task 暂停与取消
    C# Task 暂停与取消
    C# WinForm设置透明
  • 原文地址:https://www.cnblogs.com/yuyutianxia/p/7492321.html
Copyright © 2011-2022 走看看