概念
什么是字节序
字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。
小端字节序/低端字节序
- 把低有效位放在存储器的低地址端,高有效位放在存储器的高地址端。
如:在按字节寻址的存储器中往地址 0x0000 存放值 0x12345678,在存储器中的数据为:
地址 数值
0x0000 0x78
0x0001 0x56
0x0002 0x34
0x0003 0x12
- 另,数据字节序也需要考虑数据存储/传输时的单位,如下是针对8bit存储和16bit存储的情况。
大端字节序/高端字节序
- 把高有效位放在存储器的低地址端,低有效位放在存储器的高地址端。
- 如:在按字节寻址的存储器中往地址 0x0000 存放值 0x12345678,在存储器中的数据为:
地址 数值
0x0000 0x12
0x0001 0x34
0x0002 0x56
0x0003 0x78
- 另,数据字节序也需要考虑数据存储/传输时的单位,如下是针对8bit存储和16bit存储的情况。
主机字节序
主机字节序是指字节序在host机器上存储的方式,可能是大端字节序或小端字节序。
网络字节序
网络字节序是指在网络传输过程中字节序,网络之节序肯定是大端字节序。
字节间存在字节序
字节间存在字节序,在一个字节内部也存在bit order。通常情况下,在同一台机器上,bit order 与 byte order保持一致。Bit order usually follows the same endianness as the byteorder for a given computer system. That is, in a big endian system the mostsignificant bit is stored at the lowest bit address; in a little endian system,the least significant bit is stored at the lowest bit address. (http://www.linuxjournal.com/article/6788)
Note: Pay more attention on thebyte addr & bit offset in the picture.
不同字节序之间的转换
- 主机字节序转换为网络字节序
uint32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
- 网络字节序转换为主机字节序
uint32_t ntohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
如何判断当前机器是大端字节序还是小端字节序
- 系统头文件中(/usr/include/endian.h)中会定义当前系统的字节序,在字节代码中可以作如下判断,但是如下方式是在编译阶段判断,非运行时判断:
#if __BYTE_ORDER == __LITTLE_ENDIAN
…
#elif __BYTE_ORDER == __BIG_ENDIAN
…
#endif
- 实时判断当前系统的字节序
1 /*
2 * get_host_byteorder, get the byteorder ofcurrent host.
3 *
4 * return value:
5 * 1: litter endian
6 * 2: big endian
7 * -1: unknown
8 */
9 int get_host_byteorder()
10 {
11 static int order = 0;
12
13 if (order == 0){
14 unsigned short tt = 0x1234;
15 unsigned char *p = &tt;
16
17 if(*p == 0x34 && *(p+1) ==0x12) {
18 order = 1;
19 } else if (*p = 0x12 && *(p+1)== 0x34) {
20 order = 2;
21 } else {
22 order = -1;
23 }
24 }
25
26 return order;
27 }