Где находится IP-адрес в IP_ADAPTER_ADDRESSES_LH - PullRequest
0 голосов
/ 22 января 2019

На этот вопрос:

Как получить локальный IP-адрес системы Windows?

@ Реми Лебо ответил, что GetAdaptersAddresses() - это способ получить IPадрес локальной машины в Windows с использованием C ++.

Я скомпилировал пример, и в примере не распечатывается локальный IP-адрес машины.Я взглянул на структуру, которую возвращает функция (IP_ADAPTER_ADDRESSES_LH), и с удивлением обнаружил, что не вижу ссылок на фактический IP-адрес.

У меня вопрос, где находитсяIP-адрес находится в структуре IP_ADAPTER_ADDRESSES_LH?

1 Ответ

0 голосов
/ 22 января 2019

Я скомпилировал пример, и пример не распечатывает локальный IP-адрес аппарата.

GetAdaptersAddresses() всегда работал нормально для меня.

где находится IP-адрес в структуре IP_ADAPTER_ADDRESSES_LH?

В структуре потенциально может быть много IP-адресов, в зависимости от того, какой вид интересующего вас IP-адреса - Unicast, Anycast, Multicast или 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_addr или sockaddr_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 ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...