Throughout the history of computer development, there has been no unified standard for data storage. There are two commonly used rules for byte arrangement. For example, if the low-order bits of a multi-digit number are placed at smaller addresses and the high-order bits are placed at larger addresses, it is referred to as little-endian; conversely, it is called big-endian. In network applications, byte order is a factor that must be considered because different types of machines may adopt different standards, so they are all converted according to the network standard. According to reading habits, big-endian byte order is more consistent with the left-to-right reading order.
Processor Architecture
- Processors such as x86, MOS Technology 6502, Z80, VAX, and PDP-11 use little-endian byte order.
- Processors like Motorola 6800, Motorola 68000, PowerPC 970 use big-endian byte order.
- The byte order of processors such as ARM, PowerPC (excluding PowerPC 970), DEC Alpha, SPARC V9, MIPS, PA-RISC and IA64 is configurable.
Network Byte Order
Network transmission generally uses big-endian byte order, also known as network byte order or network order. The IP protocol defines big-endian as the network byte order.
The Berkeley
sockets API defined a set of conversion functions to convert 16 and 32-bit integers between network byte order and host byte order.
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostlong); // Converts a uint32_t from host byte order to network byte order
uint16_t htons(uint16_t hostshort); // Converts a uint16_t from host byte order to network byte order
uint32_t ntohl(uint32_t netlong); // Converts a uint32_t from network byte order to host byte order
uint16_t ntohs(uint16_t netshort); // Converts a uint16_t from network byte order to host byte order
If using asio
as the networking library, its internal namespace provides cross-platform adaptation functions with different names:
- boost::asio::detail::socket_ops::network_to_host_long
- boost::asio::detail::socket_ops::network_to_host_short
- boost::asio::detail::socket_ops::host_to_network_long
- boost::asio::detail::socket_ops::host_to_network_short
Visual Studio Debugger
In debugging mode, select the Debug menu, Window, and checkmark the Memory window. Within Visual Studio
, you can directly view data in memory using the debugger, as shown in the following image:
Ways to View Memory
- The window directly outputs &variable name and jumps to the corresponding variable address.
- If the variable is originally a pointer, double-click on the variable to select it and drag it to the memory window to display the content at the corresponding address.
- If the variable is not a pointer, add it to the calculation window to obtain its address, then manually copy it to the memory window.
Let’s illustrate with an example
Receive a data segment, stored in the buffer
object, convert network byte order to host byte order, resulting in body_length
being 30. The server allocates four bytes for transmitting this data.
bool NetworkMessage::decode_header()
{
// Network byte order to host byte order
body_length_ = boost::asio::detail::socket_ops::network_to_host_long(*(int *)buffer_.data());
return auto_reserve(body_length_);
}
Big-endian byte order: When observing the buffer_
content in memory,
Little-endian byte order: When observing the content of body_length_
in memory,