大端模式和小端模式的定义
a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序。
高/低字节
有一个32位无符号整型0x12345678,那么高位是什么,低位是什么呢?在十进制中我们都说靠左边的是高位,靠右边的是低位,在其他进制也是如此。就拿 0x12345678来说,从高位到低位的字节依次是0x12、0x34、0x56和0x78。
例子
32bit宽的数0x12345678
在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址 0x4000 0x4001 0x4002 0x4003
存放内容 0x78 0x56 0x34 0x12
在Big- endian模式CPU内存中的存放方式则为:
内存地址 0x4000 0x4001 0x4002 0x4003
存放内容 0x12 0x34 0x56 0x78
验证主机字节序
//联合体union中,c[0]处于低地址处,c[1]处于高地址处,如上图中地址A
//低地址存放高位,则是大端存储
//低地址存放低位,则是小端存储
bool checkCPU() // 如果是大端模式,返回真
{
union {
short s;
char c[sizeof(short)];
} un;
un.s = 0x0102;
printf("%x %x\n", &un.c[0], &un.c[1]);
if (sizeof(short) == 2) {
if (un.c[0] = 1 && un.c[1] == 2) //低地址处un.c[0]存short的高位,因此是大端存储
return true;
else if (un.c[0] == 2 && un.c[1] == 1)
return false;
}
}
int main(void)
{
if( !checkCPU())
cout<<"Little endian"<<endl;
else
cout<<"Big endian"<<endl;
return 0;
}
字节序转换函数
#include <netinet/in.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);
/**
说明: h代表(local)host;
n代表network;
s代表short;
l代表long;
*/