您的位置:首页 > 理论基础 > 计算机网络

网络通信之htonl()、htons()、ntohl()、ntohs()四个函数以及小端大端(小尾大尾)模式

2017-04-06 17:57 471 查看

前言:

今天在工作中用到htonl()这个函数,不是很理解,查阅资料之后随笔就记录下来,方便以后工作和学习翻阅。

首先需要说明的是这四个函数的头文件都需要头文件:

#include <arpa/inet.h>


htonl()函数

函数原型是:uint32_t htonl(uint32_t hostlong)

其中,hostlong是主机字节顺序表达的32位数,htonl中的h–host主机地址,to–to,n–net网络,l–unsigned long无符号的长整型(32位的系统是4字节);

函数返回值是一个32位的网络字节顺序

函数的作用是将一个32位数从主机字节顺序转换成网络字节顺序

htons()函数

函数原型是:uint16_t htons(uint16_t hostlong)

其中,hostlong是主机字节顺序表达的16位数,htons中的h–host主机地址,to–to,n–net网络,s–signed long无符号的短整型(32位的系统是2字节);

函数返回值是一个16位的网络字节顺序

函数的作用是将一个16位数从主机字节顺序转换成网络字节顺序简单的说就是把一个16位数高低位呼唤

ntohs()函数

函数原型是:uint16_t ntohs(uint16_t hostlong)

其中,hostlong是网络字节顺序表达的16位数,ntohs中的,n–net网络,to–toh–host主机地址,s–signed long有符号的短整型(32位的系统是2字节);

函数返回值是一个16位的主机字节顺序

函数的作用是将一个16位数由网络字节顺序转换为主机字节顺序简单的说就是把一个16位数高低位互换

ntohl()函数

函数原型是:uint32_t ntohs(uint32_t hostlong)

其中,hostlong是网络字节顺序表达的32位数,ntohs中的,n–net网络,to–toh–host主机地址,s–unsigned long无符号的短整型(32位的系统是4字节);

函数返回值是一个32位的主机字节顺序

函数的作用是将一个32位数由网络字节顺序转换为主机字节顺序

这些函数存在的意义

为什么存在这个函数呢?或者存在这个函数的意义?

说到这部分需要引入字节存放的两个概念一个是“大端顺序”,一个是“小端顺序”。俗称“小尾顺序”、“大尾顺序”。

简单的说就是对应数据的高字节存放在低地址,低字节存放在高地址上就是大端顺序,对应数据的高字节存放在高地址,低字节存放在低地址上就是小端顺序

比如 unsigned long hostlong = 0xa2b4c6d8;

大端顺序存放:

偏移地址 存放内容

0x00000000 0xa2

0x00000001 0xb4

0x00000002 0xc6

0x00000003 0xd8

小端顺序存放:

偏移地址 存放内容

0x00000000 0xd8

0x00000001 0xc6

0x00000002 0xb4

0x00000003 0xa2

同理推理16位数以及64位数。

一般地,在我的编译器里面设置的是小端顺序,这个可以根据自己的编译器看下设置,这里不深入说明。但是网络传输数据采用的是大端顺序。所以这才涉及到主机字节顺序和网络字节顺序,再说的详细一点,主机字节顺序可能是大端顺序或者小端顺序(这个要看编译器的设置,还有自己是用的C还是Java还是其他的语言,其各自都是不尽相同),但是网络字节顺序一定是大端顺序。

多说几句

为什么会有这个大端模式和小端模式呢?

这是因为在计算机系统中,我们是以字节为单位的,每个地址单元都对应着一个字节,一个字节为 8bit。但是在C语言中除了8bit的char之外,还有16bit的short型,32bit的long型(要看具体的编译器),另外,对于位数大于 8位的处理器,例如16位或者32位的处理器,由于寄存器宽度大于一个字节,那么必然存在着一个如何将多个字节安排的问题。因此就导致了大端存储模式和小端存储模式。例如一个16bit的short型x,在内存中的地址为0x0010,x的值为0x1122,那么0x11为高字节,0x22为低字节。对于 大端模式,就将0x11放在低地址中,即0x0010中,0x22放在高地址中,即0x0011中。小端模式,刚好相反。我们常用的X86结构是小端模式,而KEIL C51则为大端模式。很多的ARM,DSP都为小端模式。有些ARM处理器还可以随时在程序中(在ARM Cortex 系列使用REV、REV16、REVSH指令[1] )进行大小端的切换。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  函数 网络 通信 随笔