首页 资讯 应用 高压 设计 行业 低压 电路图 关于

通信网络

旗下栏目: 电力电子 通信网络 RFID LED

网络字节序和主机字节序详解

通信网络 | 发布时间:2018-05-31 | 人气: | #评论# | 本文关键字:C,C语言
摘要:我们都知道,如今的通讯方式已经趋向与多样化,异构通信(计算机软件(操作系统) + 计算机硬件(内核架构,ARM,x86)不同)也已经很普遍了,如,手机和电脑中的qq进行通信. 同时,在计

我们都知道,如今的通讯方式已经趋向与多样化,异构通信(计算机软件(操作系统) +    计算机硬件(内核架构,ARM,x86)不同)也已经很普遍了,如,手机和电脑中的qq进行通信.同时,在计算机设计之初,对内存中数据的处理也有不同的方式,(低位数据存储在低位地址处或者高位数据存储在低位地址处),然而,在通信的过程中(ISO/OSI模型和TCP/IP四层模型中),数据被一步步封装(然后加入信息首部),当传到目的段时,被一步步解封,然后获取数据

从上面我们可以看出,数据在传输的过程中,一定有一个标准化的过程,也就是说:从主机a到主机b进行通信,

a的固有数据存储-------标准化--------转化成b的固有格式

如上而言:a或者b的固有数据存储格式就是自己的主机字节序,上面的标准化就是网络字节序(也就是大端字节序)

a的主机字节序----------网络字节序 ---------b的主机字节序

主机字节序:

就是自己的主机内部,内存中数据的处理方式,可以分为两种:

大端字节序(big-endian):按照内存的增长方向,高位数据存储于低位内存中

小端字节序(little-endian):按照内存的增长方向,高位数据存储于低位内存中

1.png

但是,如何知道我们的主机是那一种的呢???这个我们可以通过程序来进行验证:

<span style="font-size:18px;">#include <stdio.h>  

  1. #include <arpa/inet.h>  

  2.   

  3. int main(){  

  4.   

  5.                 unsigned long a = 0x12345678;  

  6.                 unsigned char *p = (unsigned char *)(&a);  

  7.   

  8.                 printf("主机字节序:%0x    %0x   %0x   %0x\n",  p[0], p[1], p[2], p[3]);  

  9.   

  10.                 unsigned long b = htonl(a);  //将主机字节序转化成了网络字节序  

  11.                   

  12.                 p = (unsigned char *)(&b);  

  13.   

  14.                 printf("网络字节序:%0x    %0x   %0x   %0x\n",  p[0], p[1], p[2], p[3]);  

  15.                 return 0;  

  16.         }  </span>  

运行结果:

1.png

可以看到我的当前主机是:小端字节序

关于:htonl

  1. <span style="font-size:18px;">#include <arpa/inet.h>  

  2.   

  3.        uint32_t htonl(uint32_t hostlong);  

  4.   

  5.        uint16_t htons(uint16_t hostshort);  

  6.   

  7.        uint32_t ntohl(uint32_t netlong);  

  8.   

  9.        uint16_t ntohs(uint16_t netshort);</span>  


h是主机host,n是网络net,l是长整形long,s是短整形short,所以上面这些函数还是很好理解的

<span style="font-size:18px;">#include <stdio.h>  

  1. #include <arpa/inet.h>  

  2.   

  3. int main()  

  4. {  

  5.         struct in_addr ipaddr;  

  6.         unsigned long addr = inet_addr("192.168.1.100");  

  7.         printf("addr = %u\n", ntohl(addr));  

  8.   

  9.         ipaddr.s_addr = addr;  

  10.         printf("%s\n", inet_ntoa(ipaddr));        

  11.         return 0;         

  12. } </span>  

运行结果:

1.png

值得注意的是:

in_addr_in   inet_addr(const char *strptr);

inet_addr的参数是一个:点分十进制字符串,返回的值为一个32位的二进制网络字节序的IPv4地址,不然的话就是:INADDR_NONE

而返回值为:in_addr_t:IPv4,一般为uint32_t

所以也可以定义为:unsigned long

char * inet_ntoa(struct in_addr inaddr);

参数是一个结构体,所以要调用必须先定义一个结构体。

责任编辑:网络字节序
首页 | 电气资讯 | 应用技术 | 高压电器 | 电气设计 | 行业应用 | 低压电器 | 电路图 | 关于我们 | 版权声明

Copyright 2017-2018 电气自动化网 版权所有 辽ICP备17010593号-1

电脑版 | 移动版 原创声明:本站大部分内容为原创,转载请注明电气自动化网转载;部分内容来源网络,如侵犯您的权益请发送邮件到[email protected]联系我们删除。