inet_ntop()
函数可以将一个以网络字节序表示的IP地址转换为点分十进制的IP地址。与inet_ntoa()
函数不同,inet_ntop()
支持IPv4和IPv6地址转换,并且可以自定义输出格式,避免了静态缓冲区覆盖的问题。
在Windows下,可以使用以下方式调用inet_ntop()
函数:
#include <Ws2tcpip.h>
// af:指定要转换的协议族(AF_INET或AF_INET6)
// src:指向以网络字节序表示的IP地址的指针
// dst:指向存储结果字符串的缓冲区的指针
// size:dst缓冲区大小
// 返回值:指向结果字符串的指针,如果出错则返回NULL
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
其中,参数说明如下:
af
:指定要转换的协议族,可选值有AF_INET
(IPv4)和AF_INET6
(IPv6)src
:指向以网络字节序表示的IP地址的指针。dst
:指向存储结果字符串的缓冲区的指针。size
:缓冲区大小。
需要注意以下几点:
- 如果返回值为NULL,则说明转换失败。
- 缓冲区大小应该足够大,否则可能会截断部分结果。
- IPv4地址对应输出格式为“x.x.x.x”,IPv6地址对应输出格式为“xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx”(其中每组x表示4位16进制数)。
下面是一个使用inet_ntop()
函数将IP地址转换为字符串的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <Winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main() {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
printf("WSAStartup failed.\n");
return -1;
}
char ip[INET6_ADDRSTRLEN];
struct in_addr ipv4Addr = {0};
struct in6_addr ipv6Addr = {0};
// 将IPv4地址转换为字符串
inet_pton(AF_INET, "192.168.0.1", &ipv4Addr);
const char *strIPv4 = inet_ntop(AF_INET, &ipv4Addr, ip, INET_ADDRSTRLEN);
if (strIPv4 == NULL) {
printf("Failed to convert IPv4 address.\n");
return -1;
}
printf("%s\n", strIPv4);
// 将IPv6地址转换为字符串
inet_pton(AF_INET6, "2001:db8::1", &ipv6Addr);
const char *strIPv6 = inet_ntop(AF_INET6, &ipv6Addr, ip, INET6_ADDRSTRLEN);
if (strIPv6 == NULL) {
printf("Failed to convert IPv6 address.\n");
return -1;
}
printf("%s\n", strIPv6);
WSACleanup();
return 0;
}