在网络编程中,ai_addr 是一个指向 sockaddr 结构体的指针,其中 sa_data 是一个字符数组,用于存储套接字地址的具体信息。在这个字符数组中,前 14 个字节(部分系统中可能是16个)是用于存储地址族(AF_INET 或 AF_INET6)和端口号的,剩余的字节则是存储 IP 地址的二进制形式。而对于普通的 IPv4 地址来说,用于存储二进制形式的字节数刚好是 4 个,因此在 sa_data 中剩余的字节数就是 28 个。
示例代码如下(以获取本机 IP 地址为例):
#include
#include
#include
#include
#include
#include
#include
int main()
{
struct addrinfo hints, *res, *p;
int status;
char ipstr[INET6_ADDRSTRLEN];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC; // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM;
if ((status = getaddrinfo("localhost", NULL, &hints, &res)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
return 1;
}
for (p = res;p != NULL;p = p->ai_next) {
void *addr;
char *ipver;
if (p->ai_family == AF_INET) {
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
addr = &(ipv4->sin_addr);
ipver = "IPv4";
} else {
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
addr = &(ipv6->sin6_addr);
ipver = "IPv6";
}
inet_ntop(p->ai_family, addr, ipstr, sizeof ipstr);
printf("%s: %s\n", ipver, ipstr);
}
freeaddrinfo(res);
return 0;
}