ktb*_*677 0 c++ windows winapi
根据这个问题:
@Remy Lebeau 回答说这GetAdaptersAddresses()是使用 C++ 在 Windows 中获取本地计算机的 IP 地址的一种方法。
我编译了该示例,该示例没有打印出机器的本地IP地址。我查看了该函数返回的结构 ( IP_ADAPTER_ADDRESSES_LH),我惊讶地发现我没有看到任何对实际 IP 地址所在位置的引用。
我的问题是,IP 地址位于IP_ADAPTER_ADDRESSES_LH结构中的哪里?
我编译了该示例,该示例没有打印出机器的本地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_INET为sockaddr_in,AF_INET6为sockaddr_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)
| 归档时间: |
|
| 查看次数: |
1048 次 |
| 最近记录: |