大小端编码

       一般不同的机器有着不同的 CPU 型号,不同的 CPU 其字节序可能不一样。所谓字节序指的是对于存储需要多个字节(大于 1 字节)的整数来说,其每个字节在不同的机器内存中存储的顺序。这就是所谓的主机字节序,一般分为两类:

1.小端编码(little endian)

       对于一个整数值,如果使用小端字节序,整数的位存储在内存地址的位置,整数的位存储在内存地址的位置上(所谓的高高低低),这种序列比较符合人的思维习惯。Intel x86 系列的系统使用的是小端编码方式。

2.大端编码(big endian)

       对于一个整数值,如果使用大端字节序,整数的位存储在内存地址的位置,整数的位存储在内存地址的位置上(所谓的高低低高),这是最直观的字节序。Java 程序、Mac 机器上的程序一般是大端编码方式。

3.网络字节序

        网络字节序是 TCP/IP 协议中规定好的一种数据表示格式,它与具体的 CPU 类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释,网络字节顺序采用 big-endian 排序方式。因此为了不同的机器和系统可以正常交换数据,一般建议将需要传输的整型值转换成网络字节序。

下面是一个网络字节序转换的例子(htons函数的实现)

#include 


//判断大小端编码方式
bool isNetByteOrder()
{
    unsigned short mode = 0x1234;
    char* pmode = (char*)& mode;
    //低字节放低位  小端字节
    if (*pmode == 0x34)
        return false;    //是小端

    return true;         //是大端(网络字节序)
}

int main()
{
    //小端编码
    int hostshort = 0x1234;
    
    if (isNetByteOrder())
        std::cout << "大端编码方式" << std::endl;
    else
        std::cout << "小端编码方式, 需要转换成网络字节序" << std::endl;

    int i =  ((uint16_t)(hostshort >> 8)) | ((uint16_t)((hostshort & 0x00ff) << 8));

    std::cout << "i = " << i << std::endl;

    return 0;

}

通过打断点查看hostshort变量的编码方式,请看下图:

大小端编码_第1张图片

可以看到这里是小端编码方式,如果进行网络传输必然要转换成大端编码方式,所以下面就将hostshort两字节大小的变量转换成大端方式

大小端编码_第2张图片

最终已经转换成大端模式,这也就是htons()函数的实现。

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