c - IPv6 的 getaddrinfo() 没有意义

标签 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 返回一个 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;
}

最佳答案

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 来获取可打印的地址。

关于c - IPv6 的 getaddrinfo() 没有意义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45900237/

相关文章:

sockets - Wireshark 中的 [TCP ACKed unseen segment] 等是什么?

c - 这段代码中的CDECL是什么意思?

c++ - 将 long long 与 0 进行比较

c - 通过 TCP 客户端套接字接收数据时出现问题

c++ - cgroup C/C++ 库是否存在?

python - 如何在 Python 中通过 ZeroMQ PUB/SUB 从 Raspberry Pi 接收图像?

C++ win32 更改轨迹栏背景颜色

c++ - 为什么我的代码不渲染灰度效果

c - 访问整数最低有效位的最快方法?

c - 将完整文件名拆分为多个部分