大端 小端

在不同的CPU中,4字节整形数值1在内存空间的保存方式是不同的、4字节整数型值1可用2进制表示如下:
00000000 00000000 00000000 00000001
有些CPU用这种方式,另外一些用:
00000001 00000000 00000000 00000000来保存

因为保存方式存在差异。所以在收发数据的时候必须考虑这个;

字节序 和 网络自己序
CPU向内存保存数据的方式有2种,这意味着CPU解析数据的方式也有2种;
大端序:高位字节存放到低位地址
小端序:高位字节存放到高位地址
例如4字节int型整数:0x12345678
在大端序:
0x12 0x34 0x56 0x78
在小端序:
0x78 0x56 0x34 0x12

为了保证在收发数据的时候正确:
在通过网络传输数据时约定统一方式,这种约定称为网络字节序,统一为大端序,所以先把数据数组转化为大端序再进行网络传输;

    //初始化地址
    saddr.sin_family = AF_INET;
    saddr.sin_addr.S_un.S_addr = INADDR_ANY;
    saddr.sin_port = htons(m_port);

    //绑定socket
    int nRet;
    nRet = bind(m_clientSocket,(struct sockaddr*)&saddr,sizeof(saddr));

这就是为什么在填充sockaddr_in结构体前将数据转化为网络字节序;
下面介绍四个函数:
unsigned short htons(unsigned short);
unsigned short ntohs(unsigned short);
unsigned long htonl(unsigned long);
unsigned long ntohs(unsigned long);

ntohs 可以理解为:把short型数据从网络字节序转换为主机字节序。
用s作为后缀的,s代表2个字节,因此用于端口号转换;
L做后缀的,l代表4个字节,用于IP地址转换。

int _tmain(int argc, _TCHAR* argv[])
{
    unsigned short host_port = 0x1234;
    unsigned short net_port;
    unsigned long  host_addr = 0x12345678;
    unsigned long  net_addr;

    net_port = htons(host_port);
    net_addr = htonl(host_addr);

    printf("host_port = %x\n",host_port);
    printf("net_port = %x\n",net_port);
    printf("host_addr = %x\n",host_addr);
    printf("net_addr = %x\n",net_addr);


    getchar();

    return 0;
}

输出:host_port = 1234
net_port = 3412
host_addr = 12345678
net_addr =78563412
intel和amd的cpu一般采用小端序标准;

猜你喜欢

转载自blog.csdn.net/djb100316878/article/details/52386971