首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用IPv6的getaddrinfo()没有意义

使用IPv6的getaddrinfo()没有意义
EN

Stack Overflow用户
提问于 2017-08-26 22:41:02
回答 2查看 756关注 0票数 1

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

在我的系统中,下面的代码是打印22:B8:00:00:00:00:00:00:00:00:00:00:00:00,但我希望在某个地方出现01,因为localhost应该解析为::1

同时,sa_data只有14个字节,而IPv6地址是16个字节,因此似乎最后几个字节总是被截断,而函数不能返回IPv6地址?

有人能解释一下发生了什么事吗?我应该如何在IPv6中使用这个函数?

代码语言:javascript
复制
#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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-26 23:23:03

sockaddr结构定义以供参考:

代码语言:javascript
复制
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_addrbind()getnameinfo()等函数一起使用。您通常不需要深入了解结构定义的细节。例如,我会使用getnameinfo()NI_NUMERICHOST来获得可打印的地址。

票数 6
EN

Stack Overflow用户

发布于 2017-08-27 00:00:01

索卡德尔不被严格解释为指向sockaddr结构的指针。这种结构在不同的称谓族中被不同的解释。

因此,我们首先需要检查sa_family of sockaddrai_familyaddrinfo (在这个基础上它必须相等),并根据这个需要“重新解释”从sockaddr (类似于void*指针)到实际结构的指针。就说用联合吧:

代码语言:javascript
复制
addrinfo *addrs_out, *addr;

if (getaddrinfo("localhost", "8888", 0, &addrs_out) == NOERROR)
{
    addr = addrs_out;

    CHAR buf[256], *sz, srv[128];
    ULONG n;
    PUCHAR Byte;

    do 
    {
        union {
            sockaddr* ai_addr;
            SOCKADDR_IN* pa;
            SOCKADDR_IN6* pa6;
        };

        ai_addr = addr->ai_addr;

        if (addr->ai_family != ai_addr->sa_family)
        {
            __debugbreak();
        }

        switch (addr->ai_family)
        {
        case AF_INET6:
            Byte = pa6->sin6_addr.u.Byte, n = RTL_NUMBER_OF(pa6->sin6_addr.u.Byte), sz = buf;
            do 
            {
                sz += sprintf(sz, "%02X:", *Byte++);
            } while (--n);

            sz[-1] = 0;
            DbgPrint("AF_INET6: %s\n", buf);
            break;

        case AF_INET:
            if (0 <= RtlIpv4AddressToStringExA(&pa->sin_addr.S_un.S_addr, pa->sin_port, buf, &(n = RTL_NUMBER_OF(buf))))
            {
                DbgPrint("AF_INET: %s\n", buf);
            }
            break;
        }

        // alt print
        if (getnameinfo(ai_addr, (socklen_t)addr->ai_addrlen, buf, RTL_NUMBER_OF(buf), srv, RTL_NUMBER_OF(srv), NI_NUMERICHOST ) == NOERROR)
        {
            DbgPrint("%s:%s\n", buf, srv);
        }

    } while (addr = addr->ai_next);

    freeaddrinfo(addrs_out);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45900237

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档