|
通常习惯字符串形式的网络地址如 192.168.2.100,但在网络上进行数据通信时,需要使用的是二进制形式且为网络字节顺序的 IP 地址,如 "192.168.2.100" 对应的二进制形式为:0x6402a8c0
Linux 系统为网络地址的格式转换提供了一系列函数,man inet 获得原型如下:
| #include <netinet/in.h> | #include <arpa/inet.h> | | int inet_aton(const char *cp, struct in_addr *inp); | | in_addr_t inet_addr(const char *cp); | | in_addr_t inet_network(const char *cp); | | char *inet_ntoa(struct in_addr in); | | 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); | int inet_pton(int af, const char *src, void *dst);
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); | | 1、inet_aton() | inet_aton() 将参数 cp 指向的字符串形式的 IP 地址转换为二进制的网络字节顺序的 IP 地址,转换后的结果存于参数 inp 所指向的空间中。执行成功返回非 0 值,参数无效返回 0. | | 2、inet_addr() | 与 inet_aton() 类似,执行成功时将转换后的结果返回,参数无效返回 INADDR_NONE (该值一般为 -1)。 | 注意,此函数已经过时,推荐使用 inet_aton()。因为对于有效地址 "255.255.255.255" 它也返回 -1 (因为 -1 的补码形式为 0xFFFFFFFF ),使得用户可能将 255.255.255.255 也当成是无效的非法地址,而使用 inet_aton() 则不存在这个问题。 |
3、inet_network()
inet_network() 将参数 cp 所指向的字符串形式的网络地址转换为主机字节顺序形式的二进制 IP 地址,执行成功后返回转换后的结果,参数无效返回 -1 。
4、inet_ntoa()
该函数将值为 in 的网络字节顺序形式的二进制 IP 地址转换成以 "." 分隔的字符串形式,执行成功返回结果字符串的指针,参数无效返回 NULL 。
5、inet_makeaddr()
该函数将网络号为参数 net ,主机号为参数 host 的两个地址组合成一个网络地址,如 net 取 0xc0a802 (192.168.2.0 ,C 类网络,主机字节顺序形式),host 取 0x64 ( 主机号 0.0.0.100 ,主机字节顺序形式 ),则组合后的网络地址为:192.168.2.100,并表示为网络字节顺序形式 0x6402a8c0 。
6、inet_lnaof()
该函数从参数 in 中提取出主机地址,执行成功后返回主机字节顺序形式的主机地址。如 192.168.2.100 属于 C 类地址,则主机号为低 8 位,主机地址为 0.0.0.100 ,按主机字节顺序输出则为 0x64。
7、inet_netof()
该函数从参数 in 中提取出网络地址,执行成功返回主机字节顺序形式的网络地址。如 192.168.2.100,属于 C 类地址,则高 24 位表示网络号,网络地址为 192.168.2.0 ,按主机字节顺序输出则为 0xc0a802.
8. inet_pton()
该函数将存储再起始位置为 cp,地址协议类型为 AF 的点分十进制地址转换到 buf 中,af 的类型如果是 IPV4,则 buf 类型应该为 struct in_addr;如果 af 的类型是 IPV6,buf 类型应该为 struct in6_addr 。
9. inet_ntop()
该函数将以网络字节顺序方式存储再起始位置为 src,地址协议类型为 AF 的 32 位 IP 信息转换为点分十进制方式,并存储在长度为 len 大小的 buf 中,af 的类型如果是 IPV4,则 buf 类型应该为 struct in_addr;如果 af 的类型是 IPV6,buf 类型应该为 struct in6_addr 。
测试代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
char buffer[32];
int ret = 0;
int host = 0;
int network = 0;
unsigned int address = 0;
struct in_addr in;
in.s_addr = 0;
/*输入一个以 "." 分隔的字符串形式的IP地址*/
printf("please input your ip address:");
fgets(buffer, 31, stdin);
buffer[31] = '\0';
/*测试使用 inet_aton() 函数*/
if ((ret = inet_aton(buffer, &in)) == 0) {
printf("inet_aton: \tinvailid address\n");
} else {
printf("inet_aton: \t0x%x\n", in.s_addr);
}
/*测试使用 inet_addr() 函数*/
if ((address = inet_addr(buffer)) == INADDR_NONE) {
printf("inet_addr: \tinvalid address \n");
} else {
printf("inet_addr:\t0x%lx\n", address);
}
/*测试使用 inet_netwrok()函数*/
if ((address = inet_network(buffer)) == -1) {
printf("inet_network: \tinvalid address\n");
} else {
printf("inet_network:\t0x%lx\n", address);
}
/*测试使用 inet_ntoa() 函数*/
if (inet_ntoa(in) == NULL) {
printf("inet_ntoa: \tinvalid address\n");
} else {
printf("inet_ntoa: \t%s\n", inet_ntoa(in));
}
/*测试使用 inet_lnaof() 与 inet_netof() 函数*/
host = inet_lnaof(in);
network = inet_netof(in);
printf("inet_lnaof:\t0x%x\n", host);
printf("inet_netof:\t0x%x\n", network);
in = inet_makeaddr(network, host);
printf("inet_makeaddr:0x%x\n", in.s_addr);
return 0;
}
运行及输出:beyes@linux-beyes:~/C/network> ./test_address.exe
please input your ip address:192.168.2.100
inet_aton: 0x6402a8c0
inet_addr: 0x6402a8c0
inet_network: 0xc0a80264
inet_ntoa: 192.168.2.100
inet_lnaof: 0x64
inet_netof: 0xc0a802
inet_makeaddr:0x6402a8c0 inet_pton() 和 inet_ntop() 用法:
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
int main (int argc, char **argv)
{
struct in_addr net_addr, ret;
char buf[128];
inet_pton (AF_INET, "192.168.2.102", &ret);
printf ("%x\n", ret.s_addr);
inet_ntop (AF_INET, &ret, buf, 128);
printf ("buf=%s\n", buf);
return (0);
} 运行与输出:./inet_pton
6602a8c0
buf=192.168.2.102 说明:
第 1 行就是 192.168.2.102 转化为网络字节顺序的十六进制无符号整型数;第 2 行是把网络字节顺序转化为点分十进制的字符串。
struct in_addr 结构体的定义在 /usr/include/netinet/in.h 里:
/* Internet address. */
typedef uint32_t in_addr_t;
struct in_addr
{
in_addr_t s_addr;
}; |
|