定义
  • 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只有一个字符,转不转换都一样

  • 实际发送的数据字节流不需要转换的,比如从文件里读取出来的数据,用网络传送,接收到的数据和读取的数据一样,所以转不转换都一样。