最近学习SOCKET,将大小端存储做一个总结:
小端(Big-Endian)模式: 内存的低地址存数据的低位,内存的高地址存数据的高位。
大端(Little-Endian)模式:内存的低位存数据的高位,内存的高地址存数据的低位。
首先我们定义一个unsigned int i = 0x12345678;
我们看看内存中的存储
即:高内存地址保存高位0x12,依次向低内存地址保存0x34,0x56,0x78,所以这是小端存储。
我们经过一个Macro转换为大端存储:
#define CONVERT(N) (((unsigned int)N>>24)|((unsigned int)N<<24)|((((unsigned int)N>>16) & 0xff) <<8)|((((unsigned int)N>>8) & 0xff)<<16))
即:高内存地址保存高位0x78,依次向低内存地址保存0x56,0x34,0x12,所以这是大端存储。
在网络字节序中,一般指大端,所以在小端机器中我们需要转换成大端。
有4个函数实现这个过程:
htons:把unsigned short类型从主机序转成网络字节序
ntohs:把unsigned short类型从网络字节序转成主机序
htonl :把unsigned long类型从主机序转成网络字节序
ntohl : 把unsigned long类型从网络字节序转成主机序
我们在自己实现以上函数时候,需要判断此刻主机的字节序。
unsigned int i= 0x12345678;
char *p = (char *)&i;
或者
union
{
unsigned int i;
char a[4];
}myunion;
myunion.i = 0x12345678;
判断与0x78的关系。