目录
引文
字节序是指多字节数据在计算机内存中存储或者网络传输时各字节的存储顺序。
常见的字节顺序有两种:大端字节序(Big-endian)和小端字节序(Little-endian)。
在计算机中存储是以字节为单位,每个地址对应一个字节,一个字节8bit。在C中,除了8bit的char以外,还有16bit的short,32位的int,64位long,当然具体要由编译器决定。在计算机系统中,当物理单位的长度大于1个字节时,就要区分字节顺序。
概念
为方便理解,在如下所述的高位/低位,大端/小端等概念时,要牢记 “以字节为单位” 。
1、高位和低位
不管字节如何排序,最左边的位叫最高有效位,最右边的叫最低有效位。
以16进制0x075BCD15举例,左边07是高位,右边15是低位。
2、高地址和低地址
在内存中,多字节对象都是被存储为连续的字节序列。
假设将int整型在内存中的起始地址(首个字节存储位置)为0x1000,那么另外三个字节就存储在0x1000~0x1003。不管存储的字节顺序是怎样的,内存地址的分配都是从小到大的增长。其中0x1000称为低地址端,0x1003称为高地址端。
3、大端和小端
大端字节序:高字节(高位)存放在低地址,低字节(低位)存放在高地址。
小端字节序:低字节(低位)存放在低地址,高字节(高位)存放在高地址。
如图可以看出,大端字节序是最符合人类习惯,数值从左到右依次排列。小端字节序是最符合人的思维的字节序,是因为从人的第一观感来说低位值小,就应该放在内存地址小的地方,也即内存地址低位。
计算机电路先处理低位字节,效率比较高。因为计算就是从低位开始的,所以计算机内部很多都是小端字节序。
格式规范是为人类编写的,大端字节序更符合人类习惯。
4、网络字节序和主机字节序
- 主机字节序:小端字节序(常见的情况),由CPU架构决定。
- 网络字节序:大端字节序。TCP/IP各层协议将字节序定义为Big Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。
所以当两台主机之间要通过TCP/IP协议进行通信的时候就需要调用相应的函数进行主机序列(Little Endian)和网络序(Big Endian)的转换。
4.1字节序转换函数
#include <arpa/inet.h>
//htons函数 发 将主机字节序的端口 转换成 网络字节序的端口
uint16_t htons(uint16_t host16bitvalue); //返回网络字节序的值
//htonl函数 发 将主机字节序的IP地址 转换成网络字节序的IP地址
uint32_t htonl(uint32_t host32bitvalue); //返回网络字节序的值
//ntohs函数 收 将网络字节序的端口 转换成 主机字节序的端口
uint16_t ntohs(uint16_t net16bitvalue); //返回主机字节序的值
//ntohl函数 收 将网络字节序的IP地址
uint32_t ntohl(uint32_t net32bitvalue); //返回主机字节序的值
拓展:
处理器体系:
- 小端序体系:x86,MOS Technology 6502,Z80,VAX,PDP-11等处理器为Littleendian。
- 大端序体系:Motorola 6800,Motorola 68000,PowerPC 970,System/370,SPARC(除V9外)等处理器为Big endian
- 可配置:ARM, PowerPC (除PowerPC 970外), DEC Alpha, SPARCV9, MIPS, PA-RISC and IA64的字节序是可配置的。