inet_ntoa
、inet_aton
、inet_ntop
和 inet_pton
都是与 IP 地址转换相关的函数,它们用于将 IP 地址在字符串和二进制格式之间进行转换,但它们的使用场景和实现方式有所不同。下面是它们的详细说明和区别:
1. inet_ntoa
(网络地址转为点分十进制字符串)
- 功能:将一个以
struct in_addr
类型存储的 IPv4 地址转换为点分十进制字符串形式(例如"192.168.1.1"
)。 - 返回值:返回一个
char *
类型的字符串,表示转换后的 IP 地址。该字符串是静态分配的,因此每次调用都会覆盖之前的结果。 - 适用范围:仅适用于 IPv4 地址。
示例:
#include <stdio.h>
#include <arpa/inet.h>
int main() {
struct in_addr addr;
inet_pton(AF_INET, "192.168.1.1", &addr);
printf("IP address: %s\n", inet_ntoa(addr));
return 0;
}
输出:
IP address: 192.168.1.1
2. inet_aton
(点分十进制字符串转为网络地址)
- 功能:将一个 IPv4 地址的点分十进制字符串(例如
"192.168.1.1"
)转换为struct in_addr
类型的二进制格式。 - 返回值:返回
1
表示成功,返回0
表示失败。 - 适用范围:仅适用于 IPv4 地址。
示例:
#include <stdio.h>
#include <arpa/inet.h>
int main() {
struct in_addr addr;
if (inet_aton("192.168.1.1", &addr)) {
printf("Conversion successful: %u\n", addr.s_addr);
} else {
printf("Conversion failed\n");
}
return 0;
}
输出:
Conversion successful: 3232235777
3. inet_ntop
(网络地址转为可打印的字符串形式)
- 功能:将一个以
struct sockaddr
类型存储的网络地址(支持 IPv4 和 IPv6)转换为可打印的字符串形式。 - 返回值:返回转换后的字符串。用户需要提供一个缓冲区来存放结果。
- 适用范围:支持 IPv4 和 IPv6 地址。
示例:
#include <stdio.h>
#include <arpa/inet.h>
int main() {
struct sockaddr_in addr;
addr.sin_family = AF_INET;
inet_pton(AF_INET, "192.168.1.1", &addr.sin_addr);
char str[INET_ADDRSTRLEN];
if (inet_ntop(AF_INET, &addr.sin_addr, str, INET_ADDRSTRLEN)) {
printf("IP address: %s\n", str);
} else {
printf("Conversion failed\n");
}
return 0;
}
输出:
IP address: 192.168.1.1
4. inet_pton
(点分十进制字符串转为网络地址)
- 功能:将一个字符串表示的 IPv4 或 IPv6 地址转换为二进制网络格式,并存储在
struct sockaddr
类型的结构体中。 - 返回值:成功时返回
1
,失败时返回0
,如果遇到无效地址格式会返回-1
,并且errno
会被设置为EINVAL
。 - 适用范围:支持 IPv4 和 IPv6 地址。
示例:
#include <stdio.h>
#include <arpa/inet.h>
int main() {
struct sockaddr_in addr;
addr.sin_family = AF_INET;
if (inet_pton(AF_INET, "192.168.1.1", &addr.sin_addr) == 1) {
printf("Conversion successful\n");
} else {
printf("Conversion failed\n");
}
return 0;
}
输出:
Conversion successful
总结对比
函数 | 功能 | 支持地址类型 | 输入格式 | 输出格式 |
---|---|---|---|---|
inet_ntoa | 将 struct in_addr 转换为 IPv4 字符串 | IPv4 | struct in_addr (二进制) | 字符串(点分十进制) |
inet_aton | 将 IPv4 字符串转换为 struct in_addr | IPv4 | 点分十进制字符串 | struct in_addr (二进制) |
inet_ntop | 将 struct sockaddr 转换为字符串 | IPv4 / IPv6 | struct sockaddr (二进制) | 字符串(点分十进制 / IPv6) |
inet_pton | 将 IPv4 / IPv6 字符串转换为 struct sockaddr | IPv4 / IPv6 | 点分十进制 / IPv6 字符串 | struct sockaddr (二进制) |
关键区别:
inet_ntoa
和inet_aton
只支持 IPv4,而inet_ntop
和inet_pton
支持 IPv4 和 IPv6。inet_ntoa
返回的字符串是静态分配的,每次调用会被覆盖,而inet_ntop
需要提供一个缓冲区存放结果。inet_aton
和inet_pton
都需要操作内存结构(如struct in_addr
或struct sockaddr
),但是inet_pton
更通用,支持 IPv6。inet_ntop
和inet_pton
是现代应用中更推荐的函数,因为它们支持 IPv6。
理解这些区别之后,可以根据需要选择合适的函数进行 IP 地址的转换操作。