getaddrinfo不返回ipv6详细信息

时间:2018-12-07 14:11:23

标签: c++ sockets network-programming getaddrinfo

我在获取ipv6 using getaddrinfo()时遇到了问题:

#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>

int main()
{
        int soc = 00;
        struct addrinfo hints,*results,*res;
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        hints.ai_flags = AI_PASSIVE;

        int m = getaddrinfo("myhost","2018",&hints,&results);
        if (m<0)
        {
                printf("getaddrinfo error :  %s\n", gai_strerror(m));
                return 1;
        }
        res=results;
        do
        {
                if(res->ai_family == AF_INET6)
                {
                        struct sockaddr_in6* a= (struct sockaddr_in6*)res->ai_addr;
                        char straddr[INET6_ADDRSTRLEN];
                        inet_ntop(AF_INET6, &a->sin6_addr, straddr, sizeof(straddr));
                        printf("IP v6 - %s\n",straddr);
                }
                if(res->ai_family == AF_INET)
                {
                        struct sockaddr_in* b= (struct sockaddr_in*)res->ai_addr;
                        const char* dotted_decimal1 = inet_ntoa(b->sin_addr);
                        printf("IP v4 - %s\n",dotted_decimal1);
                }
        }
        while((res=res->ai_next) !=NULL);

        return 0;
}

输出:

IP v4 - xx.xx.xx.xx

自从我设置了hints.ai_family = AF_UNSPEC以来,它都应该同时向我返回详细信息(ipv4ipv6)。 但是它仅返回ipv4的详细信息。

注意:在命令ifconfig上,我可以看到ipv4ipv6的地址。

> $ ifconfig
> eth3      Link encap:Ethernet  HWaddr xx:xx:xx:xx:xx:xx
> inet addr:x.x.x.x  Bcast:x.x.x.x  Mask:255.255.255.128
> inet6 addr: xx::xx:xx:xx:xx/64 Scope:Link
  1. 一个人可以向我解释为什么不选择ipv6吗?

  2. 我需要在主机(Linux)上进行任何更改吗?

我已经删除了实际的ip详细信息,并替换为xxxx。

2 个答案:

答案 0 :(得分:4)

要检索本地地址(因为您正在使用AI_PASSIVE),可以(并且应该)将node参数设置为NULL,而不是根据{{ 3}}:

  

如果在AI_PASSIVE中指定了hints.ai_flags标志,并且节点是NULL,则返回的套接字地址将适用于bind(2)插入将{{ 1}}个连接。

此外,accept(2)支持inet_ntop(),因此您可以摆脱AF_INET语句,并为两个地址族无条件使用if

尝试一下:

inet_ntop()

答案 1 :(得分:2)

  

由于我已经设置了hints.ai_family = AF_UNSPEC,它应该同时向我返回两个详细信息(ipv4和ipv6)

不,不应该。 getaddrinfo API不保证同时返回IPv4和IPv6地址。它返回与给定主机名关联的IP地址类型。

为了确保您的代码正常运行,您可以通过google.com80端口(即

)检查443主机
 int m = getaddrinfo("google.com","80",&hints,&results);

此检查会同时在我的Linux PC中返回IPv4和IPv6地址(仅供参考,我也没有全局IPv6地址)。

如果需要检索本地IPv6地址,我建议在Linux中使用getifaddrs或读取/proc/net/if_inet6文件,在Windows中使用GetAdaptersAddresses
 另外请注意,您的IPv6地址范围是本地链接,由OS自动生成。

相关问题