一、大小端(Endianness)
是指在计算机科学中用来描述多字节数据类型(如16位整数、32位整数等)在内存中的存储顺序。具体来说,它指的是一个数据的最低有效字节(Least Significant Byte, LSB)和最高有效字节(Most Significant Byte, MSB)是如何存储的。注意只有一个字节以上的才需要转换,不同电脑和CPU使用的大小端不一致,所以在跨平台时需要做到一致以保证数据的准确性
注:不同的CPU上运行不同的操作系统,字节序也是不同的,参见下表。
处理器 操作系统 字节排序
Alpha 全部 Little endian
HP-PA NT Little endian
HP-PA UNIX Big endian
Intelx86 全部 Little endian <-----x86系统是小端字节序系统
Motorola680x() 全部 Big endian
MIPS NT Little endian
MIPS UNIX Big endian
PowerPC NT Little endian
PowerPC 非NT Big endian <-----PPC系统是大端字节序系统
RS/6000 UNIX Big endian
SPARC UNIX Big endian
IXP1200 ARM核心 全部 Little endian
二、大端(Big-Endian)
在大端模式下,数据的最高有效字节存放在内存的最低地址处,而最低有效字节则存放在最高地址处。这种排列方式与阅读书本的方式相似,即从左到右读取数值。
三、小端(Little-Endian)
在小端模式下,情况正好相反:最低有效字节存放在内存的最低地址处,而最高有效字节则存放在最高地址处。这种方式在一定程度上更符合数字电路中处理数据的习惯。
四、区别与联系
区别:主要在于字节序的不同,即多字节数据类型的各个字节在内存中的排列顺序。
联系:两者都是为了正确地表示和操作多字节数据类型,只是采用了不同的字节排序方式。
五、转换函数的使用场景
网络协议通常采用大端字节序来传输数据,这被称为网络字节序。因此,当不同字节序的系统之间需要通过网络进行通信时,就需要将主机字节序转换为网络字节序,或者反之。这就是htonl()、htons()等函数的用途:
#include <arpa/inet.h> // 提供了htonl, htons, ntohl, ntohs等函数
htonl():将32位无符号整数从主机字节序转换为网络字节序。
htons():将16位无符号整数从主机字节序转换为网络字节序。
ntohl():将32位无符号整数从网络字节序转换为主机字节序。
ntohs():将16位无符号整数从网络字节序转换为主机字节序。
对于单个字节的数据,由于只有一个字节,不存在字节序的问题,所以不需要使用这些转换函数。
六、使用场景及示例
- 发送数据到远程服务器
假设你要通过TCP/IP协议发送一个32位的整数给远程服务器:
uint32_t local_num = 0x12345678;
uint32_t net_num = htonl(local_num);
send(socket_fd, &net_num, sizeof(net_num), 0);
- 接收来自远程服务器的数据
当你从远程服务器接收到一个32位的整数时,你需要将其转换为主机字节序以便正确解析:
uint32_t net_num;
recv(socket_fd, &net_num, sizeof(net_num), 0);
uint32_t local_num = ntohl(net_num);
- 处理文件或数据流
如果你正在开发一个跨平台的应用程序,可能需要考虑不同平台上字节序的差异,以确保数据的一致性。