Запрос локального IP-адреса

Мне нужно знать мой фактический локальный IP-адрес (т.е. не адрес обратной связи) из приложения Windows 8 WinRT/Metro. Есть несколько причин, по которым мне это нужно. Самое простое - это то, что в пользовательском интерфейсе приложения я хотел бы показать текст типа "IP-адрес вашей локальной сети: [IP запрашивается из кода]".

Мы также используем адрес для некоторых дополнительных сетевых коммуникаций. Эти комманды совершенно корректны, потому что все работает, если я посмотрю на IP-адрес в панели управления, а затем жестко закодирую его в приложении. Просить пользователя в диалоговом окне пойти посмотреть адрес и ввести его вручную - это то, чего я действительно очень хочу избежать.

Я думаю, что это не будет сложной задачей, чтобы получить адрес программно, но мои навыки поисковой системы и Stackru выходят пустыми.

На этом этапе я начинаю рассматривать выполнение цикла широковещания / прослушивания UDP, чтобы услышать мой собственный запрос и извлечь из него адрес, но это действительно похоже на хаккейский ключ. Есть ли где-нибудь API в новом материале WinRT, который поможет мне?

Обратите внимание, что я сказал "WinRT приложение. Это означает, что типичные механизмы, такие как Dns.GetHostEntry или же NetworkInterface.GetAllInterfaces() не собираюсь работать.

2 ответа

Решение

После долгих поисков я нашел нужную информацию, используя NetworkInformation и HostName.

NetworkInformation.GetInternetConnectionProfile извлекает профиль подключения, связанный с подключением к Интернету, используемым в настоящее время на локальном компьютере.

NetworkInformation.GetHostNames извлекает список имен хостов. Это не очевидно, но это включает адреса IPv4 и IPv6 в виде строк.

Используя эту информацию, мы можем получить IP-адрес сетевого адаптера, подключенного к Интернету, например:

public string CurrentIPAddress()
{
    var icp = NetworkInformation.GetInternetConnectionProfile();

    if (icp != null && icp.NetworkAdapter != null)
    {
        var hostname =
            NetworkInformation.GetHostNames()
                .SingleOrDefault(
                    hn =>
                    hn.IPInformation != null && hn.IPInformation.NetworkAdapter != null
                    && hn.IPInformation.NetworkAdapter.NetworkAdapterId
                    == icp.NetworkAdapter.NetworkAdapterId);

        if (hostname != null)
        {
            // the ip address
            return hostname.CanonicalName;
        }
    }

    return string.Empty;
}

Обратите внимание, что HostName имеет свойства CanonicalName, DisplayName и RawName, но все они, похоже, возвращают одну и ту же строку.

Мы также можем получить адреса для нескольких адаптеров с кодом, подобным следующему:

private IEnumerable<string> GetCurrentIpAddresses()
{
    var profiles = NetworkInformation.GetConnectionProfiles().ToList();

    // the Internet connection profile doesn't seem to be in the above list
    profiles.Add(NetworkInformation.GetInternetConnectionProfile());

    IEnumerable<HostName> hostnames =
        NetworkInformation.GetHostNames().Where(h => 
            h.IPInformation != null &&
            h.IPInformation.NetworkAdapter != null).ToList();

    return (from h in hostnames
            from p in profiles
            where h.IPInformation.NetworkAdapter.NetworkAdapterId ==
                  p.NetworkAdapter.NetworkAdapterId
            select string.Format("{0}, {1}", p.ProfileName, h.CanonicalName)).ToList();
}

О принятом ответе, вам просто нужно это:

HostName localHostName = NetworkInformation.GetHostNames().FirstOrDefault(h =>
                    h.IPInformation != null &&
                    h.IPInformation.NetworkAdapter != null);

Вы можете получить локальный IP-адрес следующим образом:

string ipAddress = localHostName.RawName; //XXX.XXX.XXX.XXX

Используемые пространства имен:

using System.Linq;
using Windows.Networking;
using Windows.Networking.Connectivity;
Другие вопросы по тегам