定义
-
Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。(逻辑上的低低高高)
-
Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
缘由
因CPU硬件不同,使用的存储字节顺序可能不同,分为大端和小端,所以大小端其实将的就是字节序。为了在网络传输中,不同的硬件可以相互通信,TCP/IP 协议规定使用大端模式(Big-Endian).因TCP/IP协议族是用来解决网络通信的,所以TCP/IP协议中使用的字节序通常称之为网络字节序。
构架
字节序按照CPU架构分:
- Big Endian : PowerPC、IBM、Sun、ARM
- Little Endian : x86、DEC、ARM
示例
int型的整数在计算机中占4个字节,整数0x01020304的两种表示方法:
低地址———–>高地址
04 | 03 | 02 | 01 —>方法1:小端模式(高字节放到低地址上) |
01 | 02 | 03 | 04 —>方法2:大端模式(高字节放到高地址上) 网络字节序 |
判断大小端
bool isBigEndian()
{
union
{
int a;
char b;
}num;
num.a = 0x1234;
return ( num.b == 0x12 )
}
转换
1. 宏处理
#define __SWP16(A) (( ((uint16)(A) & 0xff00) >> 8) | (( (uint16)(A) & 0x00ff) << 8))
#define __SWP32(A) ((( (uint32)(A) & 0xff000000) >> 24) | (( (uint32)(A) & 0x00ff0000) >> 8) | (( (uint32)(A) & 0x0000ff00) << 8) | (( (uint32)(A) & 0x000000ff) << 24))
2. linux的4个转换函数
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”,代表“主机”;
- “to”,代表“转换到”;
- “n”,代表“网络”;
- ”s”,代表“短型数据”
- “l”,代表“长型数据”
短型(两个字节)和长型(四个字节)
什么时候考虑大小端问题
-
需要让网络认识的数据,是需要转换,比如ip地址,端口号,传输一些整型数的参数
-
协议解析方面的数字类型需要转换,如果传输的数据包,头部记录了大小的信息,那么这个记录了大小的整型数需要转换
-
char,char[] 这种数据类型不需考虑,因为char只有一个字符,转不转换都一样
-
实际发送的数据字节流不需要转换的,比如从文件里读取出来的数据,用网络传送,接收到的数据和读取的数据一样,所以转不转换都一样。