• 网络字节序和主机字节序


    1、大端、小端字节序

    考虑一个16位整数,它由2个字节组成。内存中存储这两个字节有两种方法:一种是将低序字节存储在起始地址,这称为小端(little-endian)字节序;另一种方法是将高序字节存储在起始地址,这称为大端(big-endian)字节序。如下所示:

     术语“大端”和“小端”表示多个字节值的哪一端(小端或大端)存储在该值的起始地址。

    遗憾的是,这两种字节序之间没有标准可循,两种格式都有系统使用。比如,Inter x86、ARM核采用的是小端模式,Power PC、MIPS UNIX和HP-PA UNIX采用大端模式。

    2、网络字节序和主机字节序

    网络字节序

      网络字节序是TCP/IP中规定好的一种数据表示格式,它与具体的CPU类型、操作系统等无关,从而可以保证数据在不同主机之间传输时能够被正确解释。网络字节序采用big endian排序方式。

    主机字节序

      不同的机器主机字节序不相同,与CPU设计有关,数据的顺序是由cpu决定的,而与操作系统无关。我们把某个给定系统所用的字节序称为主机字节序(host byte order)。比如x86系列CPU都是little-endian的字节序。

      由于这个原因不同体系结构的机器之间无法通信,所以要转换成一种约定的数序,也就是网络字节顺序。

    网络字节序与主机字节序之间的转换函数:htons(), ntohs(), htons(),htonl(),位于头文件<netinet/in.h>,htons和ntohs完成16位无符号数的相互转换,htonl和ntohl完成32位无符号数的相互转换。

    在使用little endian的系统中,这些函数会把字节序进行转换;

    在使用big endian类型的系统中,这些函数会定义成空宏;

    在网络程序开发时 或是跨平台开发时,也应该注意保证只用一种字节序,不然两方的解释不一样就会产生bug。

    3、IP地址的三种表示格式及在开发中的应用

    1)点分十进制表示格式

    2)网络字节序格式

    3)主机字节序格式

    用IP地址127.0.0.1为例:

      第一步   127     .         0         .         0         .        1                 把IP地址每一部分转换为8位的二进制数。

      第二步 01111111     00000000     00000000     00000001      =   2130706433   (主机字节序)

      然后把上面的四部分二进制数从右往左按部分重新排列,那就变为:

      第三步 00000001     00000000     00000000    01111111        =   16777343        (网络字节序)

    eg:

      struct sockaddr_in addrSrv;

    //  addrSrv.sin_addr.S_un.S_addr=htonl(2130706433);  
      addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
      addrSrv.sin_family=AF_INET;
      addrSrv.sin_port=htons(6000);

    4、inet_aton()、inet_addr()和inet_aton()函数

    头文件: <arpa/inet.h>

    1)int inet_aton(const char *strptr, struct in_addr *addrptr);

    将strptr所指C字符串转换成一个32位的网络字节序二进制值,并通过指针addrptr来存储。若成功则返回1,否则返回0。

    2)in_addr_t inet_addr(const char *strptr)

    若字符串有效,则返回值为32位的网络字节序二进制值,否则为INADDR_NONE。

    该函数存在一个问题,所有2^32个可能的二进制值都是有效的IP地址(0.0.0.0---255.255.255.255),但是当出错时该函数返回INADDR_NONE常值(通常是一个32位均为1的值)。这意味着点分十进制数串255.255.255.255不能由该函数处理,因为它的二进制值用来指示该函数失败。所以该函数已经被废弃,应该尽量用inet_aton()函数,或者将要说到的inet_pton()函数。

    3)char *inet_ntoa(struct in_addr inaddr);

    将一个32位的网络字节序二进制值IPv4地址转换成相应的点分十进制数串。该函数以一个结构而不是以指向该结构的一个指针作为其参数。

    返回:指向一个点分十进制数串的指针

    5、inet_pton()和inet_ntop()函数

    这两个函数是随着IPv6出现的新函数,对于IPv4地址和IPv6地址都适用。函数名中p和n分别代表表达(presentation)和数值(numeric)。

    头文件: <arpa/inet.h>

     

     

     

     

     

     

     

     

     总结这几个转换函数:

  • 相关阅读:
    流行-Manifold学习理解与应用
    狠心奶奶自断亲情,28年后孙女拒绝相见:人有没有不原谅的权利?
    学术论文常用词汇总结(待更新)
    机动车驾驶(2)--- 老司机经验
    关于MySQL数据导出导入
    php5.6-lumen与php5.6-phalcon性能对比
    win7(64bit)+python3.5+pyinstaller3.2安装和测试
    WARNING: Can not get binary dependencies for file...
    一些不错的计算机书籍
    PHP扩展类ZipArchive实现压缩解压Zip文件和文件打包下载
  • 原文地址:https://www.cnblogs.com/xingguang1130/p/11643446.html
Copyright © 2020-2023  润新知