多字节的数值在内存中高低位的排列方式会影响所表示的数值。根据字节高低位排序方式的不同,可以分为:大端字节序(big endian)和 小端字节序(little endian)。
大端字节序
大端字节序是指一个整数的高位字节存储在内存的低地址处,可以理解为数值的高位部分靠前存储。以0x12343abcd为例,假如存储在内存中的起始地址为0x00000000,则0x1234abcd在内存中的存储为:
地址0x00000000处存储内容为:0x12
地址0x00000001处存储内容为:0x34
地址0x00000002处存储内容为:0xab
地址0x00000003处存储内容为:0xcd
小端字节序
小端字节序是指一个整数的低位字节存储在内存的低地址处,可以理解为数值的低位部分靠前存储。以0x12343abcd为例,假如存储在内存中的起始地址为0x00000000,则0x1234abcd在内存中的存储为:
地址0x00000000处存储内容为:0xcd
地址0x00000001处存储内容为:0xab
地址0x00000002处存储内容为:0x34
地址0x00000003处存储内容为:0x12
网络字节序和主机字节序的转换
#include<arpa/inet.h>
uint32_t htonl(uint32_t hostlong);
uint32_t htons(uint32_t hostshort);
uint32_t ntohl(uint32_t hostlong);
uint32_t ntohl(uint32_t hostshort);
- h表示host,n表示network,l表示32 位长整数,s表示16位短整数。
- htonl表示将32位长整数从主机字节序转换为网络字节序。
- 如果主机是小端字节序,这些函数将参数做相应大小端转换后返回。
- 如果主机是大端字节序,这些函数不做转换将参数原封不动的返回。
注意
- 发送主机通常将发送缓冲区中的数据按内存地址的从低到高的顺序发出;
- 接收后主机把从网络上接收到的字节依次保存到接收缓冲区中,也是按内存地址由低到高的顺序保存;
- 因此,网络数据流的地址应该是这样规定:先发出的数据是低地址,后发出的地址是高地址;
- 不管这台主机是大端机还是小端机,都会按这个TCP/IP规定的网络字节序来发送/接收数据;
- 如果当前发送主机是小端,就要先将数据转化为大端,否则就忽略,直接发送出去。
主机字节序对网络通信的影响:
不同主机字节序的两台主机进行通信时有可能造成数据二义。
因此规定:在网络通信中统一使用大端字节序作为网络字节序进行通信。
主机字节序会对存储时大于1个字节的数据类型造成影响。