大端模式和小端模式

1,在计算机中一般讲字节序分为两类:Big-Endian(大端字节序) 和 Little-Endian(小端字节序)。
a) Little-Endian 高位字节在前,低位字节在后。
b) Big-Endian 低位字节在前,高位字节在后。
c) 网络字节序:TCP/IP各层协议将字节序定义为Big-Endian,因此TCP/IP协议中使用的字节序通常称之为网络字节序

大端模式和小端模式_第1张图片

2,在x86的计算机中,一般采用的是小端字节序

#include                                                                                                    
int main()
{
    int b = 0x017f;
    int *p = &b;
    char d = 0 ;
    for(int i = 0;i < 4;i++)
    {
        d = *((char*)p+i);
        printf("d is %d \n",d);    
    }   
}

d is 127
d is 1
d is 0
d is 0

3,为了避免因为Endianness造成的通信问题,及便于软件开发者编写易于平台移植的程序,特别定义了一些C语言预处理的宏来实现网络字节与主机字节次序之间的相互转换。htons()和htonl()用来将主机字节次序转成网络字节次序,前者应用于16位无符号数,后者应用于32位无符号数。Linux系统中t头文件是netinet/in.h,ntohs()和ntohl()实现反方向的转换。进行转换bsd socket提供了转换的函数有四个:
htons 把unsigned short类型从主机序转换到网络序
htonl 把unsigned long类型从主机序转换到网络序
ntohs 把unsigned short类型从网络序转换到主机序
ntohl 把unsigned long类型从网络序转换到主机序

 

typedef unsigned short int uint16;
typedef unsigned long int uint32;
// 短整型大小端互换
#define BigLittleSwap16(A)  ((((uint16)(A) & 0xff00) >> 8) | /
                                                 (((uint16)(A) & 0x00ff) << 8))
// 长整型大小端互换
#define BigLittleSwap32(A)  ((((uint32)(A) & 0xff000000) >> 24) | /
                                                 (((uint32)(A) & 0x00ff0000) >> 8) | /
                                                 (((uint32)(A) & 0x0000ff00) << 8) | /
                                                 (((uint32)(A) & 0x000000ff) << 24))
// 本机大端返回1,小端返回0
int checkCPUendian()
{
       union  

      {
              unsigned long int i;
              unsigned char s[4];
       }c;
       c.i = 0x12345678;
       return (0x12 == c.s[0]);
}
// 模拟htonl函数,本机字节序转网络字节序
unsigned long int HtoNl(unsigned long int h)
{
       // 若本机为大端,与网络字节序同,直接返回
       // 若本机为小端,转换成大端再返回
       return checkCPUendian() ? h : BigLittleSwap32(h);
}
// 模拟ntohl函数,网络字节序转本机字节序
unsigned long int NtoHl(unsigned long int n)
{
       // 若本机为大端,与网络字节序同,直接返回
       // 若本机为小端,网络数据转换成小端再返回
       return checkCPUendian() ? n : BigLittleSwap32(n);
}
// 模拟htons函数,本机字节序转网络字节序
unsigned short int HtoNs(unsigned short int h)
{
       // 若本机为大端,与网络字节序同,直接返回
       // 若本机为小端,转换成大端再返回
       return checkCPUendian() ? h : BigLittleSwap16(h);
}
// 模拟ntohs函数,网络字节序转本机字节序
unsigned short int NtoHs(unsigned short int n)
{
       // 若本机为大端,与网络字节序同,直接返回
       // 若本机为小端,网络数据转换成小端再返回
       return checkCPUendian() ? n : BigLittleSwap16(n);
}

你可能感兴趣的:(大端模式和小端模式)