IPv6环回地址的sin6_scope_id是什么?

时间:2019-10-29 00:26:46

标签: windows sockets ipv6 loopback

我想创建一个绑定到本地计算机上任何端口的套接字,以便可以在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 = ????;

1 个答案:

答案 0 :(得分:1)

某些套接字大师可能知道设置它的直接方法。但是,只需向系统查询即可。这将为您正确设置“ flowinfo”和“ scope_id”。

一般方法是这样:

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

枚举从此api返回的ifaddrs的列表,直到找到在IFF_LOOPBACK成员上设置了ifa_flags位的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);