字符串 IP 地址和二进制 IP 地址的转换

目录

inet_xxx() 函数

1. inet_aton()函数

2. inet_addr()函数

3. inet_network()函数

4. inet_ntoa()函数

5. inet_makeaddr()函数

6. inet_lnaof()函数

7. inet_netof()函数

inet_pton()和 inet_ntop()函数

1. inet_pton()函数

2. inet_ntop()函数

注意:


人类理解的IP地址表达方式是类似127.0.0.1这样的字符串;而计算机理解的则是像01111111 00000000 00000000 00000001(127.0.0.1)这样表达的 IP 地址方式。在网络程序的设计中,经常需要进行字符串表达方式的 IP 地址和二进制的 IP 地址之间的转换,将对此类函数进行介绍。

函数原型见下:

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

//只适用于IPV4 ----------------------------------------------------------

//定义在<netinet/in.h> 中
struct in_addr
{
	unsigned long int s_addr; //IP 地址
};

//将cp中点分十进制的 IP 地址转为地址结构 in_addr 值
int inet_aton(const char *cp, struct in_addr *inp );

//将字符串转换为 in_addr 值
in_addr_t inet_addr(const char *cp); 

//字符串地址的网络部分转为 in_addr 类型
in_addr_t inet_network(const char *cp); 

//将 in_addr 结构地址转为字符串
char *inet_ntoa(struct in_addr in); 

//将网络地址和主机地址合成为 IP 地址
struct in_addr inet_makeaddr(int net, int host); 

//获得地址的主机部分
in_addr_t inet_lnaof(struct in_addr in); 

//获得地址的网络部分
in_addr_t inet_netof(struct in_addr in); 


//适用于IPV4 和 IPV6 -------------------------------------------------------

//字符串类型的IP地址转换为二进制类型
int inet_pton(int af, const char *src, void *dst); 

//二进制类型转换为字符串类型的IP地址
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); 

inet_xxx() 函数

Linux 操作系统有一组函数用于网络地址的字符串形式和二进制形式之间的转换,其形式为 inet_xxx()。

1. inet_aton()函数

inet_aton()函数将在 cp 中存储的点分十进制字符串类型的 IP 地址,转换为二进制的 IP 地址,转换后的值保存在指针 inp 指向的结构 structure in_addr 中。当转换成功时返回值为非0;当传入的地址非法时,返回值为0。

2. inet_addr()函数

inet_addr()函数将 cp 中存储的点分十进制字符串类型的 IP 地址转换为二进制的 IP 地址,IP地址是以网络字节序表达的。如果输入的参数非法,返回值为 INADDRNONE (通常为 -1),否则返回值为转换后的 IP 地址。

这个函数是函数 inet_aton()的缩减版,由于值-1(0xFFFFFFFF)同时可以理解为是合法 IP 地址255.255.255.255 的转换结果,所以不能使用这个函数转换 IP 地址 255.255.255.255

3. inet_network()函数

inet_network()函数将 cp 中存储的点分十进制字符串类型的 IP 地址,转换为二进制的 IP 地址,IP地址是以网络字节序表达的。当成功时返回32位表示 IP 地址,失败时返回值为 -1。参数 cp 中的值有可能采用以下形式。
    a.b.c.d:这种形式指定了 IP 地址的全部4个段,是一个完全的 IP 地址转换,这种情况下函数 inet_network()与函数 inet_addr()完全一致。
    a.b.c:这种形式指定了 IP 地址的前3个段,a.b 解释为 IP 地址的前16位,c,解释为后面的16位。例如172.16.888会将888解释为 IP地址的后16位。
    a.b:这种形式指定了 IP 地址的前两个段,a 为 IP 地址的前8位,b 解释为后面的24位。例如,172.888888会将888888解释为 IP 地址的后3段。
    a:当仅为一部分时,a 的值直接作为 IP 地址,不做字节序转换。

4. inet_ntoa()函数

inet_ntoa()函数将一个参数 in 所表示的 Internet 地址结构转换为点分十进制的4段式字符串 IP 地址,其形式为 a.b.c.d。返回值为转换后的字符串指针,此内存区域为静态的,有可能会被覆盖,因此函数并不是线程安全的。
例如,将二进制的 IP 地址0x1000000000000001使用函数 inet_ntoa()转换为字符串类型的结果为127.0.0.1。

5. inet_makeaddr()函数

一个主机的 IP 地址分为网络地址和主机地址,inet_makeaddr()函数将主机字节序的网络地址 net 和主机地址 host合并成一个网络字节序的 IP 地址。
下面的代码将网络地址127和主机地址1合并成一个 IP 地址:127.0.0.1:

unsigned long net, hst;
net = 0x0000007E;
host = 0x00000001;
struct in_addr ip = inet_makeaddr(net, hst);

6. inet_lnaof()函数

inet_lnaof()函数返回 IP 地址的主机部分。例如,下面的例子返回 IP 地址127.0.0.1的主机部分:

const char addr = "127.0.0.1";
unsigned long ip = inet_network(addr);
unsigned 1ong host_id = inet_1naof(ip); 

7. inet_netof()函数

inet_netof()函数返回 IP 地址的网络部分。例如,下面的例子返回 IP 地址127.0.0.1的网络部分。

const char addr = "127.0.0.1";
unsigned long ip = inet_network(addr);
unsigned long network_id = inet_netof( ip);

inet_pton()和 inet_ntop()函数

inet_pton()和 inet_ntop()函数函数是一套安全的协议无关的地址转换函数。所谓的“安全”是相对于 inet_aton()函数的不可重入性来说。这两个函数都是可以重入的,并且这些函数支持多种地址类型,包括IPv4和IPv6。

1. inet_pton()函数

inet_pton()函数将字符串类型的 IP 地址转换为二进制类型,其原型如下。第1个参数 af 表示网络类型的协议族,在IPv4下的值为 AF_INET; 第2个参数 src 表示需要转换的字符串;第3个参数 dst 指向转换后的结果,在IPv4下, dst 指向结构 struct in_addr 的指针。

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int inet_pton(int af, const char *src, void *dst);

当函数 inet_pton() 的返回值为 -1 的时候,通常是由于 af 所指定的协议族不支持造成的,此时 errno 的返回值为 EAFNOSUPPORT; 当函数的返回值为0时,表示 src 指向的值不是合法的 IP 地址;当函数的返回值为正值时,表示转换成功。

2. inet_ntop()函数

inet_ntop()函数将二进制的网络 IP 地址转换为字符串,函数原型如下所示。第1个参数 af 表示网络类型的协议族,在IPv4下的值为 AF_INET ;第2个参数 src 为需要转换的二进制 IP 地址,在IPv4下,src 指向一个 struct in_addr 结构类型的指针; 第3个参数 dst 指向保存结果缓冲区的指针;第4个参数 cnt 的值是 dst 缓冲区的大小。

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);

inet_ntop()函数返回一个指向 dst 的指针。当发生错误时,返回 NULL。当 af 设定的协议族不支持时,errno 设置为 EAFNOSUPPORT;当 dst 缓冲区过小的时候 errno 的值为 ENOSPC 。
 

注意:

函数 inet_addr()、 inet_network()的返回值为 -1 时表示错误,这占用了255.255.255.255的值,因此可能存在缺陷。

函数 inet_ntoa()的返回值为一个指向字符串的指针,这个一块静态地址,这块内存函数 inet_ntoa()每次调用都会重新覆盖,因此函数并不安全,可能存在某种隐患,

将字符串 IP 地址转换为 in_addr 时,注意字符串中对 IP 地址的描述,上述函数假设字符串中以0开始表示八进制,以0x开始表示十六进制,将按照各进制对字符串进行解析,例如 IP 地址192.168.000.037最后一段的037表示的是八进制的数值,即相当于192.168.0.31。

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值