IP_ADAPTER_ADDRESSES_LH 中的 IP 地址在哪里

ktb*_*677 0 c++ windows winapi

根据这个问题:

如何获取Windows系统的本地IP地址?

@Remy Lebeau 回答说这GetAdaptersAddresses()是使用 C++ 在 Windows 中获取本地计算机的 IP 地址的一种方法。

我编译了该示例,该示例没有打印出机器的本地IP地址。我查看了该函数返回的结构 ( IP_ADAPTER_ADDRESSES_LH),我惊讶地发现我没有看到任何对实际 IP 地址所在位置的引用。

我的问题是,IP 地址位于IP_ADAPTER_ADDRESSES_LH结构中的哪里?

Rem*_*eau 5

我编译了该示例,该示例没有打印出机器的本地IP地址。

GetAdaptersAddresses()对我来说一直很好。

IP 地址位于 IP_ADAPTER_ADDRESSES_LH 结构中的什么位置?

该结构中可能有许多IP 地址,具体取决于您感兴趣的 IP 地址类型- 单播、任播、多播或 DnsServer。对于本地分配的 IP,您通常仅使用单播地址:

  • IP_ADAPTER_ADDRESSES_LH::FirstUnicastAddress字段指向一个IP_ADAPTER_UNICAST_ADDRESS_LH结构链接列表,每个 IP 地址对应一个条目。使用IP_ADAPTER_UNICAST_ADDRESS_LH::Next字段来循环列表(MSDN 示例显示了这样的循环,但它只计算列表中的元素数量,并不会打印出列表的内容)。

  • IP_ADAPTER_UNICAST_ADDRESS_LH::Address字段包含格式上的实际 IP 地址SOCKET_ADDRESS

  • SOCKET_ADDRESS::lpSockaddr字段是一个SOCKADDR*指针。您可以将其按原样传递给套接字 API,例如bind().

  • 如果您想对 IP 地址执行某些操作(例如显示它),则必须将指针类型转换SOCKET_ADDRESS::lpSockAddr为 或sockaddr_in*sockaddr_in6*具体取决于 IP 地址是 IPv4 还是 IPv6(使用该SOCKADDR::sa_family字段来确定正确的类型 -AF_INETsockaddr_in,AF_INET6sockaddr_in6)。然后您可以根据需要访问sockaddr_in::sin_addrorsockaddr_in6::sin6_addr字段,其中包含 IP 地址的实际字节。

例如:

PIP_ADAPTER_ADDRESSES pAddresses = ...; // allocate buffer as needed...
ULONG ulSize = ...; // size of allocated buffer...

if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME, NULL, pAddresses, &ulSize) == 0)
{
    for (PIP_ADAPTER_UNICAST_ADDRESS_LH *pAddress = pAddresses->FirstUnicastAddress;
        pAddress != NULL;
        pAddress = pAddress->Next)
    {
        SOCKADDR *pSockAddr = pAddress->Address.lpSockaddr;
        switch (pSockAddr->sa_family)
        {
            case AF_INET: {
                sockaddr_in *pInAddr = (sockaddr_in*) pSockAddr;
                // use pInAddr->sin_addr as needed...
                break;
            }

            case AF_INET6: {
                sockaddr_in6 *pIn6Addr = (sockaddr_in6*) pSockAddr;
                // use pIn6Addr->sin6_addr as needed...
                break;
            }
        }
    }
}

// free pAddresses as needed ...
Run Code Online (Sandbox Code Playgroud)