使用IPv6的getaddrinfo()没有意义

时间:2017-08-26 22:41:02

标签: c sockets winapi ipv6 getaddrinfo

我不明白为什么getaddrinfo没有返回有效的IPv6地址。

在我的系统上,下面的代码正在打印22:B8:00:00:00:00:00:00:00:00:00:00:00:00,但我预计会在某个地方01,因为localhost应解析为::1

同时,sa_data只有14个字节,而IPv6地址是16个字节,所以看起来最后几个字节总是被切断,而函数可以&#t; t 返回IPv6地址?

有人可以解释一下发生了什么吗?我该如何在IPv6中使用此功能?

#include <stdio.h>
#include <WinSock2.h>
#include <WS2TCPIP.h>
#pragma comment(lib, "WS2_32")

int main(int argc, char *argv[])
{
    WSADATA wsadata;
    WSAStartup(0x0002, &wsadata);
    addrinfo addr_hints = { 0, PF_INET6, SOCK_DGRAM, IPPROTO_UDP }, *addrs_out;
    getaddrinfo("localhost", "8888", &addr_hints, &addrs_out);
    fprintf(stderr,
        "%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 0]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 1]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 2]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 3]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 4]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 5]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 6]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 7]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 8]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[ 9]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[10]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[11]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[12]),
        static_cast<unsigned char>(addrs_out->ai_addr->sa_data[13]));
    freeaddrinfo(addrs_out);
    return 0;
}

2 个答案:

答案 0 :(得分:6)

sockaddr结构定义供参考:

struct sockaddr {
    ushort  sa_family;
    char    sa_data[14];
};


struct sockaddr_in6 {
    short   sin6_family;
    u_short sin6_port;
    u_long  sin6_flowinfo;
    struct  in6_addr sin6_addr;
    u_long  sin6_scope_id;
};

ai_family == AF_INET6 ai_addr实际指向struct sockaddr_in6时。您要打印的前几个字节是sin6_portsin6_flowinfo。 IPv6地址在后面。

编辑添加:

您可以ai_addr直接使用bind()getnameinfo()等功能。您通常不需要深入了解结构定义细节。例如,我会使用getnameinfo()NI_NUMERICHOST来获取可打印的地址。

答案 1 :(得分:1)

  

sockaddr并未严格解释为指向a的指针   sockaddr结构。该结构的解释不同   不同地址家庭的背景。

所以我们需要首先检查来自sa_family的{​​{1}}或来自ai_family的{​​{1}}(在此基础中它必须相等)并根据此需要&#34;重新解释& #34;从sockaddr(这类似addrinfo指针)到真实结构的指针。说使用联盟:

void*