inet_addr
和 inet_pton
都是用于处理 IP 地址转换的函数,但它们在功能、兼容性、安全性等方面存在一定差异,下面为你详细介绍:
1. inet_addr
功能
inet_addr
函数的主要功能是将一个点分十进制表示的 IPv4 地址字符串转换为一个 32 位的网络字节序整数。该函数定义在 <winsock.h>
或 <winsock2.h>
头文件中。
原型
in_addr_t inet_addr(const char *cp);
- 参数:
cp
是指向点分十进制 IPv4 地址字符串的指针,例如"192.168.1.1"
。 - 返回值:如果转换成功,返回一个 32 位的网络字节序整数;如果输入的字符串不是有效的 IPv4 地址,返回
INADDR_NONE
(即0xffffffff
) 。
示例代码
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
const char* ip_str = "192.168.1.1";
in_addr_t addr = inet_addr(ip_str);
if (addr != INADDR_NONE) {
printf("Converted IP address: %u\n", addr);
} else {
printf("Invalid IP address\n");
}
return 0;
}
缺点
- 错误处理不友好:
INADDR_NONE
与有效的 IPv4 地址255.255.255.255
冲突,这使得无法准确区分转换失败和输入的是255.255.255.255
地址的情况。 - 仅支持 IPv4:不能处理 IPv6 地址,在需要支持 IPv6 的现代网络环境中不适用。
2. inet_pton
功能
inet_pton
函数的作用是将点分十进制的 IP 地址字符串转换为二进制形式,它既支持 IPv4 地址,也支持 IPv6 地址。该函数定义在 <arpa/inet.h>
或 <ws2tcpip.h>
头文件中。
原型
#include <ws2tcpip.h>
int inet_pton(int af, const char *src, void *dst);
- 参数:
af
:地址族,AF_INET
表示 IPv4,AF_INET6
表示 IPv6。src
:指向点分十进制 IP 地址字符串的指针。dst
:指向存储二进制 IP 地址的缓冲区的指针。
- 返回值:
- 成功时返回 1。
- 如果
src
不是有效的 IP 地址,返回 0。 - 发生错误时返回 -1,并设置
errno
。
示例代码
#include <stdio.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
return 1;
}
struct in_addr addr;
const char* ip_str = "192.168.1.1";
if (inet_pton(AF_INET, ip_str, &addr) == 1) {
printf("Converted IP address: %u\n", addr.s_addr);
} else {
printf("Invalid IP address\n");
}
WSACleanup();
return 0;
}
优点
- 更好的错误处理:通过不同的返回值可以清晰地判断转换是否成功以及是否发生错误。
- 支持 IPv6:能够处理 IPv6 地址,适应现代网络的发展需求。
总结
在现代网络编程中,尤其是需要支持 IPv6 或者对错误处理有较高要求的场景下,推荐使用 inet_pton
函数替代 inet_addr
。而在一些只需要处理 IPv4 地址且对错误处理要求不高的简单场景中,inet_addr
仍然可以使用。