banner
cells

cells

为美好的世界献上 bug

Network byte order

Byte Order#

Byte order: the order in which bytes are stored.

Byte order is related to CPU architecture. Typically, x86 architecture uses little-endian byte order, which determines the order in which data is stored in memory.

When transmitting data in network communication, byte order needs to be standardized to ensure proper transmission and parsing of data.

There are two ways to store data: big-endian and little-endian.

Big-endian: the most significant byte is stored at the lowest address, and the least significant byte is stored at the highest address (low to high).

Little-endian: the most significant byte is stored at the highest address, and the least significant byte is stored at the lowest address (low to low).

For the hexadecimal number 0x1234, 12 is the most significant byte and 34 is the least significant byte. The terms high address and low address refer to the size of the addresses. For example, if there are two addresses 0x1010 and 0x1011, 0x1010 is the low address and 0x1011 is the high address.

Determining the Byte Order of the Local Machine#

// 1 Byte = 8 bits (8 binary digits represent one byte)
// 1 hexadecimal digit represents 4 bits
// short occupies 2 bytes = 16 bits
// Casting to char*, the first address (low address) obtained occupies 1 byte
// Dereferencing this low address and casting it to short
// Comparing it with the least significant and most significant bytes in the original data
// If it is equal to the most significant byte, it indicates big-endian (low to high)
// If it is equal to the least significant byte, it indicates little-endian (low to low)

// If it is big-endian, the high-order byte of the data is stored in the low address
// The most significant byte is 0x12
// &i retrieves the low address
// (short)*(char *)&i == 0x12
bool isBigEndian() {
    short i = 0x1234;
    return (short)*(char *)&i == 0x12;
}

// If it is little-endian, the low-order byte of the data is stored in the low address
// The least significant byte is 0x34
// &i retrieves the low address
// (short)*(char *)&i == 0x34
bool isLittleEndian() {
    short i = 0x1234;
    return (short)*(char *)&i == 0x34;
}

Simplified version:

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

Converting between the Byte Order of the Local Machine and Network Byte Order#

Network byte order typically uses big-endian byte order.

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();

When using these APIs, make sure that the input parameters and return results are unsigned integers to avoid sign extension issues.

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.