字节顺序,又称端序或尾序(英语:Endianness)。在计算机科学领域中,是跨越多字节的程序对象的存储规则。在几乎所有的机器上,多字节对象都被存储为连续的字节序列。例如在C语言中,一个类型为int的变量x地址为0x100,那么其对应地址表达式&x的值为0x100。且x的四个字节将被存储在存储器的0x100, 0x101, 0x102, 0x103位置。
而存储地址内的排列则有两个通用规则。一个多位的整数将按照其存储地址的最低或最高字节排列。如果最低有效位在最高有效位的前面,则称小端序;反之则称大端序。在网络应用中,字节序是一个必须被考虑的因素,因为不同机器类型可能采用不同标准的字节序,所以均按照网络标准转化。
例如假设上述变量x类型为int,位于地址0x100处,它的十六进制为0x12345678,地址范围为0x100~0x103字节,其内部排列顺序依赖于机器的类型。
字节序 | 0x100 | 0x101 | 0x102 | 0x103 |
小端 | 0x78 | 0x56 | 0x34 | 0x12 |
大端 | 0x12 | 0x34 | 0x56 | 0x78 |
网络传输一般采用大端序,也被称之为网络字节序,或网络序。IP协议中定义大端序为网络字节序。Berkeley套接字定义了一组转换函数,用于16和32bit整数在网络序和本机字节序之间的转换。htonl,htons用于本机序转换到网络序;ntohl,ntohs用于网络序转换到本机序。
一、 字节序转换函数
#include <arpa/inet.h> uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);
二、 示例代码
#include <stdio.h> #include <arpa/inet.h> union order { unsigned int value; unsigned char data[sizeof(int)]; }; void print(union order d) { for(int i=0; i<sizeof(int); i++) { printf("%p:\t0x%x\n", &d.data[i], d.data[i]); } } int main(void) { union order d; d.value = 0x12345678; printf("Host byte order:\n"); print(d); d.value = htonl(d.value); printf("network byte order:\n"); print(d); return 0; }
三、 运行结果
[root@localhost workspace]# gcc byte_order.c -o byte_order -std=gnu99 -Wall [root@localhost workspace]# ./byte_order Host byte order: 0x7fffa9ed8e20: 0x78 0x7fffa9ed8e21: 0x56 0x7fffa9ed8e22: 0x34 0x7fffa9ed8e23: 0x12 network byte order: 0x7fffa9ed8e20: 0x12 0x7fffa9ed8e21: 0x34 0x7fffa9ed8e22: 0x56 0x7fffa9ed8e23: 0x78
至此,我们可以确定主机字节序为小端,网络字节序为大端。