关于htonl函数

关于htonl函数,第1张

这个是个字节序转换函数,具体的比较多,我就摘抄了,反正是一个转换而已,不是简单的转为网络字节,主要是因为主机字和网络字,字序不同~

htonl就是把本机字节顺序转化为网络字节顺序

所谓网络字节顺序(大尾顺序)就是指一个数在内存中存储的时候“高对低,低对高”(即一个数的高位字节存放于低地址单元,低位字节存放在高地址单元中)。但是计算机的内存存储数据时有可能是大尾顺序或者小尾顺序。

先举个例子:

int a = 0x403214

int b = htonl(a)

我在VC++6.0调试这段代码,发现

&a的值为:0x0012ff44

其中0x0012ff44、0x0012ff45、0x0012ff46、0x0012ff47这四个单元的值依次为:14、32、40、00,即0x403214这个数的高位部分存放在高位地址中,低位部分存放在低位地址中,即小尾顺序。

&b的值为:0x0012ff40

其中0x0012ff40、0x0012ff41、0x0012ff42、0x0012ff43这四个单元的值依次为:00、40、32、14,即把原数0x403214的高位部分存放在低位地址中,低位部分存放在高位地址中。

由此可见,如果一个数以小尾顺序存储,经htonl函数调用后这个数的高地位字节会完全颠倒过来成为一个新的数。这个新的数在机器内部其实还是以小尾顺序存储的,但是相对于原来的数而言相当于是变成大尾顺序的了。

long型的0x40写完整为:0x 00 00 00 40,共四个字节,调用htonl后四个字节颠倒顺序,为0x 40 00 00 00。

同样,0x40 00 00 00调用htonl后变为0x 00 00 00 40,即0x40

现在我们很幸运,因为我们有很多的函数来方便地 *** 作 IP 地址。没有 必要用手工计算它们,也没有必要用"<<" *** 作来储存成长整字型。

首先,假设你已经有了一个sockaddr_in结构体ina,你有一个IP地址"132.241.5.10" 要储存在其中,你就要用到函数inet_addr(),将IP地址从 点数格式转换成无符号长整型。使用方法如下:

ina.sin_addr.s_addr = inet_addr("132.241.5.10")

注意,inet_addr()返回的地址已经是网络字节格式,所以你无需再调用 函数htonl()。

我们现在发现上面的代码片断不是十分完整的,因为它没有错误检查。 显而易见,当inet_addr()发生错误时返回-1。记住这些二进制数字?(无符 号数)-1仅仅和IP地址255.255.255.255相符合!这可是广播地址!大错特 错!记住要先进行错误检查。

好了,现在你可以将IP地址转换成长整型了。有没有其相反的方法呢? 它可以将一个in_addr结构体输出成点数格式?这样的话,你就要用到函数 inet_ntoa()("ntoa"的含义是"network to ascii"),就像这样:

printf("%s",inet_ntoa(ina.sin_addr))

它将输出IP地址。需要注意的是inet_ntoa()将结构体in-addr作为一 个参数,不是长整形。同样需要注意的是它返回的是一个指向一个字符的 指针。它是一个由inet_ntoa()控制的静态的固定的指针,所以每次调用 inet_ntoa(),它就将覆盖上次调用时所得的IP地址。例如:

char *a1, *a2

.

.

a1 = inet_ntoa(ina1.sin_addr)/* 这是198.92.129.1 */

a2 = inet_ntoa(ina2.sin_addr)/* 这是132.241.5.10 */

printf("address 1: %s ",a1)

printf("address 2: %s ",a2)

输出如下:

address 1: 132.241.5.10

address 2: 132.241.5.10

假如你需要保存这个IP地址,使用strcopy()函数来指向你自己的字符指针。

htonl函数:将主机数转换成无符号长整型的网络字节顺序。本函数将一个32位数从主机字节顺序转换成网络字节顺序。

我猜测你问的就是这个,socket通讯前要把IP地址改成网络字节的顺序。


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/bake/11605126.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存