一、网络字节序和主机字节序
网络字节序和主机字节序是计算机网络中常用的两种数据存储格式。
主机字节序: 指的是在计算机内部存储数据时采用的字节排序方式。对于一个长为4个字节的整数,若采用大端字节序,则该整数在内存中的存储顺序是:以地址递增顺序依次存储其最高位到最低位的每个字节;若采用小端字节序,则该整数的字节则按照倒序的方式存储于内存中。
例如,在大端字节序中,数字127的存储方式如下:
网络字节序: 指的是一种标准的字节序,规定了数据在网络数据传输中采用的字节序,即大端字节序,也被称为网络序(Network Byte Order)。理由是因为不同的机器可能采用不同的主机字节序,而网络通信必须使用统一的字节序,这样才能保证不同系统之间的通信正常进行。
二、htonl()和ntohl
在C/C++语言中,可以使用函数htonl()
和ntohl()
等将主机字节序转为网络字节序(大端字节序),并将网络字节序转换为主机字节序。其中,htonl()
表示将32位整数从主机字节序转换为网络字节序,ntohl()
则表示将32位整数从网络字节序转换为主机字节序,其他还有htons()
和ntohs()
等类似的函数用于16位整型。
下面是一个简单的示例,演示了如何使用 htonl()
和 ntohl()
函数将主机字节序和网络字节序相互转换:
#include <stdio.h>
#include <arpa/inet.h> // 包含 htons() 和 ntohl() 函数的头文件
int main()
{
unsigned int host_num = 0x12345678; // 本机使用的数据,被视为主机字节序
unsigned int net_num = htonl(host_num); // 转换为网络字节序
printf("host num: 0x%x\n", host_num);
printf("net num: 0x%x\n", net_num);
// 将网络字节序恢复为主机字节序
unsigned int restored_num = ntohl(net_num);
printf("restored num: 0x%x\n", restored_num);
return 0;
}
运行结果如下所示:
host num: 0x12345678
net num: 0x78563412
restored num: 0x12345678
可以看到,在本机上调用 htonl()
函数将主机字节序转换为网络字节序后,输出的结果的顺序与我们期望的顺序完全相反。但在另一台计算机上接收到此数据时,这个字节序列就按照我们期望的大端字节序进行解释,最后恢复成原来的主机字节序。