【问题标题】:What is sin6_scope_id for the IPv6 loopback address?IPv6 环回地址的 sin6_scope_id 是什么?
【发布时间】:2020-02-24 06:08:50
【问题描述】:

我想创建一个绑定到本地机器上任何端口的套接字,这样我就可以在 Windows 上模拟socketpair()。当我希望这个套接字是 IPv6 时,我应该为sin6_scope_id 设置什么值?我是否真的必须枚举适配器并找到环回适配器才能填写该字段?

换句话说,我需要做什么才能绑定到任何本地端口?

struct sockaddr_in6 addr;
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(0);
addr.sin6_flowinfo = 0;
addr.sin6_addr = in6addr_loopback;
addr.sin6_scope_id = ????;

【问题讨论】:

    标签: windows sockets ipv6 loopback


    【解决方案1】:

    一些套接字专家可能知道设置它的直接方法。但是查询系统更容易。这将为您正确设置“flowinfo”和“scope_id”。

    一般做法是这样的:

    调用getifaddrs 以获取ifaddrs 实例的列表。

    枚举从此 api 返回的 ifaddrs 列表,直到找到在 ifa_flags 成员上设置了 IFF_LOOPBACK 位的 AF_INET6 适配器。这是您要绑定到的适配器。

    现在您有了指向 ifaddrs 实例的指针,将其 ifa_addr 成员转换为 (sockaddr_in6*)。将此结构复制到您自己的addr 并设置端口。

    下面的一些示例代码:

    struct sockaddr_in6 addr = {0};
    ifaddrs* pList = NULL;
    ifaddrs* pAdapterFound = NULL;
    ifaddrs* pAdapter = NULL;
    getifaddrs(&pList);
    pAdapter = pList;
    while (pAdapter)
    {
        if ((pAdapter->ifa_addr != NULL) && 
            (family == pAdapter->ifa_addr->sa_family == AF_INET6) &&
            (pAdapter->ifa_flags & IFF_LOOPBACK))
        {
            pAdapterFound = pAdapter;
            break;
        }
        pAdapter = pAdapter->ifa_next;
    }
    
    if (pAdapterFound)
    {    
        // C++ way to copy the sockaddr_in6 struct
        addr = *(reinterpret_cast<sockaddr_in6*>(pAdapterFound->ifa_addr));  // C++
    
        // If you are coding in C instead of C++
        // memcpy(&addr, pAdapterFound->ifa_addr, sizeof(addr));
    
        addr.sin6_port = htons(0); // or whatever port you want to bind to
    }
    
    freeifaddrs(pList);
    

    欢迎您引用我称为GetSocketAddressForAdapter 的辅助函数。您可以按如下方式调用它:

    GetSocketAddressforAdapter(AF_INET6, "::1", 0, &address);
    

    【讨论】:

    • 这适用于 Windows;我想我需要GetAdaptersAddresses?我这样做的全部原因是因为 Windows 没有 socketpair 并且没有其他方法可以中断 selectWSAPoll。顺便说一句,在 C++ 中使用memcpy(或std::memcpy)也可以避免使用reinterpret_cast 违反别名规则。
    • 您应该使用 Windows 标签指定您的问题。 GetAdaptersAddresses 的问题在于它不会返回 sockaddr_in6 结构。您可能需要 SIOCGLIFNUM 套接字 ioctl 代替。你能向我解释一下别名问题吗?
    猜你喜欢
    • 2021-12-21
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    相关资源
    最近更新 更多