Вопрос по c#, windows-runtime – Запрос локального IP-адреса

31

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

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

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

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

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

Windows знает только об интерфейсах, если кто-то назначает IP-адрес локальной сети сетевому устройству, то есть это адрес (он абсолютно действителен). Что именно вы пытаетесь сделать с IP-адресом? Вы вряд ли сможете выполнять UDP-трансляцию / прослушивание чего-либо, кроме того IP-адреса, о котором знает интерфейс, чаще всего это адрес локальной сети, недопустимый за пределами указанной сети. Security Hound
@Ramhound: не уверен, что я должен смотреть - и эта документация не согласуется с поведением, которое я вижу с Consumer Preview и VS11 Beta. Например, документы показываютNetworkIntrface.GetAllNetworkInterfaces() должно работать, но его не существует. ctacke
Взгляни наmsdn.microsoft.com/en-us/library/windows/apps/… Security Hound

Ваш Ответ

2   ответа
1

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

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;
Этот ответ совершенно неверный. Это может работать в определенной конфигурации сети, но попробуйте добавить виртуальные машины в систему и виртуальные коммутаторы, и первым возвращаемым именем хоста может быть IP-адрес виртуального коммутатора, который совершенно непригоден для использования.
34

После долгих поисков я нашел нужную вам информацию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();
}
@AndrewB: я только что попробовал оба метода выше, и они работают для меня. 10.0.0.1 - это стандартный частный IP-адрес, например 192.168.x.x. Кажется, хорошо для меня.
Действительно, вызов. Моей команде скоро потребуется поддержка Windows 2003+ (включая Windows 8). Беда в том, что такая простая вещь, как нахождение IP-адреса текущего компьютера, требует какого-либо "рытья". совсем.
Я бы рекомендовал добавить & amp; hn.Type == HostNameType.Ipv4 в запросе. Потому что я получу ошибку, если у вас тоже есть IpV6, как и у меня, и из-за SingleOrDefault будет сгенерировано исключение.
hn.NetworkAdapter был заменен наhn.IPInformation.NetworkAdapter в финальной версииWindows.Networking.Connectivity.NetworkInformation учебный класс. Пересмотренная версияvar hostname линия должна выглядеть примерно такvar hostname = NetworkInformation.GetHostNames().SingleOrDefault(hn => hn.IPInformation != null && hn.IPInformation.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId == icp.NetworkAdapter.NetworkAdapterId);.
Вот это да. Похоже, поддержка Windows 8 будет проблемой в заднице.

Похожие вопросы