• 大端?小端?网络字节序?


    不同CPU中,4字节整数1在内存空间的存储方式是不同的。4字节整数1可用2进制表示如下:

    00000000 00000000 00000000 00000001

    有些CPU以上面的顺序存储到内存,另外一些CPU则以倒序存储,如下所示:

    00000001 00000000 00000000 00000000

    若不考虑这些就收发数据会发生问题,因为保存顺序的不同意味着对接收数据的解析顺序也不同。

    大端序和小端序

    CPU向内存保存数据的方式有两种:

    • 大端序(Big Endian):高位字节存放到低位地址(高位字节在前)。
    • 小端序(Little Endian):高位字节存放到高位地址(低位字节在前)。

    仅凭描述很难解释清楚,不妨来看一个实例。假设在 0x20 号开始的地址中保存4字节 int 型数据 0x12345678,对于大端序,最高位字节 0x12 存放到低位地址,最低位字节 0x78 存放到高位地址。

    大端序CPU保存方式如下图所示:

     图1:整数 0x12345678 的大端序字节表示

    小端序的保存方式如下图所示:

     图2:整数 0x12345678 的小端序字节表示

    网络字节序和主机字节序

    网络字节序是确定的,而主机字节序是多样的。

    网络字节序统一为大端序。

    主机字节序既可以是大端的,也可以是小端的,现代计算机大多采用小端字节序。

    不同CPU保存和解析数据的方式不同(主流的Intel系列CPU为小端序),小端序系统和大端序系统通信时会发生数据解析错误。

    为了避免这个问题,约定数据在不同计算机之间传递时都采用大端字节序,也叫作网络字节序。通信时,发送方需要把数据转换成网络字节序(大端字节序)之后再发送,接收方再把网络字节序转成自己的字节序。主机A先把数据转换成大端序再进行网络传输,主机B收到数据后先转换为自己的格式再解析。

    网络字节序转换函数

    htons() 用来将当前主机字节序转换为网络字节序,其中h代表主机(host)字节序,n代表网络(network)字节序,s代表short,htons 是 h、to、n、s 的组合,可以理解为”将short型数据从当前主机字节序转换为网络字节序“。

    常见的网络字节转换函数有:

    • htons():host to network short,将short类型数据从主机字节序转换为网络字节序。
    • ntohs():network to host short,将short类型数据从网络字节序转换为主机字节序。
    • htonl():host to network long,将long类型数据从主机字节序转换为网络字节序。
    • ntohl():network to host long,将long类型数据从网络字节序转换为主机字节序。

    通常,以s为后缀的函数中,s代表2个字节short,因此用于端口号转换;以l为后缀的函数中,l代表4个字节的long,因此用于IP地址转换。

    例(在这个例子中使用了htons函数):

    //创建sockaddr_in结构体变量
    struct sockaddr_in serv_addr;
    memset(&serv_addr, 0, sizeof(serv_addr));  //每个字节都用0填充
    serv_addr.sin_family = AF_INET;  //使用IPv4地址
    serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");  //具体的IP地址
    serv_addr.sin_port = htons(1234);  //端口号
  • 相关阅读:
    Oracle创建表空间用户等
    centos7安装neo4j
    Linux 介绍和命令超详细
    Go 变量声明
    Manjaro 安装 & 配置
    Go Golang安装及环境变量配置
    python3集合与常用操作
    正则以及re库的使用
    Requests 库安装
    数据库-数据库管理系统-数据库系统
  • 原文地址:https://www.cnblogs.com/cyx-b/p/12454495.html
Copyright © 2020-2023  润新知