一文彻底搞懂大小端字节序

一文彻底搞懂大小端字节序


文章目录

  • 一文彻底搞懂大小端字节序
    • 1.基本概念
        • 1.1大端字节序(big-endian)
        • 1.2小端字节序(little-endian)
    • 2. 常用处理器架构大小端模式
    • 3. 如何查看系统的大小端模式
        • 3.1 `dpkg-architecture`
        • 3.2 `lscpu `
        • 3.3 `file `
        • 3.4 程序判断
    • 4. 网络通信字节序及其转换
        • 4.1 本机字节序和网络字节序
        • 4.2 网络通信时的字节序转换
    • 5.结论

1.基本概念

字节序(byte order)表征计算机对于多字节数据在内存中的存储顺序,对于单字节数据则没有字节序概念;

struct Test {
    int a = 0x11223344;
    short b = 0x8899;
    short c = 0xabcd;
};

1.1大端字节序(big-endian)

高位字节存储在低地址, 低位字节存储在高位地址,如Fig1.所示:
一文彻底搞懂大小端字节序_第1张图片

Fig1. 大端字节序存储示例图

1.2小端字节序(little-endian)

高位字节存储在高地址, 低位字节存储在低地址,如Fig2.所示:
一文彻底搞懂大小端字节序_第2张图片

Fig2. 小端字节序存储示例图

2. 常用处理器架构大小端模式

X86 ARM PowerPC 51
小端 小端 大端 大端

3. 如何查看系统的大小端模式

3.1 dpkg-architecture

只适用于debain发行版, 比如ubuntu,结果如Fig3.所示。
一文彻底搞懂大小端字节序_第3张图片

Fig3. dpkg-architecture结果

3.2 lscpu

适用于debian和redhat等, 比如ubuntu, centos等,结果如Fig4.所示。
一文彻底搞懂大小端字节序_第4张图片

Fig4. lscpu结果

3.3 file

更通用,结果如Fig5.所示。
在这里插入图片描述

Fig5. file结果

3.4 程序判断

//返回true代表小端, 返回false代表大端
bool isLittleEndian(void)
{
    union check
    {
        int idata;
        char cdata;
    } var;

    var.idata = 1;
    return(var.cdata == 1);
}

4. 网络通信字节序及其转换

4.1 本机字节序和网络字节序

  • 本机字节序指的是通信双方的主机本地字节序,根据CPU架构的不同,有大端和小端两种字节序;而网络字节序指的是大端字节序

4.2 网络通信时的字节序转换

  • 相同字节序的平台在进行网络通信时可以不进行字节序转换(将错就错),但是跨平台进行网络数据通信时必须进行字节序转换,如Fig6.所示。
  • 不同字节序的平台进行通信时小端一方必须进行字节序转换,大端方可以不用进行字节序转换,因为平台为大端时转换API默认不工作,如Fig7.所示。
    一文彻底搞懂大小端字节序_第5张图片
Fig6. 无字节序转换数据流图

一文彻底搞懂大小端字节序_第6张图片

Fig7. 网络字节序转换数据流图

5.结论

  • 异构平台进行多字节网络通信时要注意本机字节序和网络字节序的转换,对于大端平台和小端平台的通信, 小端平台必须进行字节序转换,大端平台非必须。
  • 因此JSON和XML等跨平台的数据交换格式(字符串)应用比较广泛,无需考虑字节序。

你可能感兴趣的:(c++)