banner
cells

cells

为美好的世界献上 bug

网络字节序

字节序#

字节序:存放字节的顺序。

字节序与 CPU 架构相关,通常 x86 架构使用小端序,字节序决定数据在内存中存储的顺序。

在网络通信传输数据时需要统一字节序,以确保能够正常的传输和解析数据。

存储数据方式有:大端序(Big-Endian)和 小端序(Little-Endian)。

大端序:高位字节存储在低地址,低位字节存储在高地址(低对高)。

小端序:高位字节存储在高地址,低位字节存储在低地址(低对低)。

对于 0x1234 十六进制的数,12 是高位字节,34 是低位字节。而高地址和低地址指的是地址的大小,例如有两个地址 0x10100x10110x1010 就是低地址,0x1011 就是高地址。

判断本机字节序#

// 1 Byte = 8 bit(8 位二进制代表一个字节)
// 1 位十六进制代表 4 bit
// short 占 2 Byte = 16 bit
// char 占 1 Byte = 8 bit
// 强转为 char *,后取出的首地址(低位地址)占 1 Byte
// 将这个低位地址解引用后转为 short
// 与原始数据中的低位和高位进行比较
// 如果等于高位则说明为大端序(低对高)
// 如果等于低位则说明为小端序(低对低)

// 如果是大端序,低地址存储数据的高位字节
// 高位字节是 0x12
// &i 取出的是低地址
// (short)*(char *)&i == 0x12
bool isBigEndian() {
    short i = 0x1234;
    return (short)*(char *)&i == 0x12;
}

// 如果是小端序,低地址存储数据的低位字节
// 低位字节是 0x34
// &i 取出的是低地址
// (short)*(char *)&i == 0x34
bool isLittleEndian() {
    short i = 0x1234;
    return (short)*(char *)&i == 0x34;
}

简单写法:

bool isBigEndian() {
    short i = 1;
    return *(char *)&i != 1;
}

转换本机字节序与网络字节序#

网络字节序通常使用大端字节序

POSIX API#

// host to network unsigned short
htons();

// host to network unsigned long
htonl();

// network to host unsigned short
ntohs();

// network to host unsigned long
ntohl();

Boost Asio API#

// host to network unsigned short
boost::asio::detail::socket_ops::host_to_network_short();

// host to network unsigned long
boost::asio::detail::socket_ops::host_to_network_long();

// network to host unsigned short
boost::asio::detail::socket_ops::network_to_host_short();

// network to host unsigned long
boost::asio::detail::socket_ops::network_to_host_long();

在使用这些 API 时,应该确保输入参数和返回结果都是无符号整型,否则可能存在符号拓展问题。

加载中...
此文章数据所有权由区块链加密技术和智能合约保障仅归创作者所有。