Получить локальный IP-адрес


301

В интернете есть несколько мест, которые показывают вам, как получить IP-адрес. И многие из них выглядят так:

String strHostName = string.Empty;
// Getting Ip address of local machine...
// First get the host name of local machine.
strHostName = Dns.GetHostName();
Console.WriteLine("Local Machine's Host Name: " + strHostName);
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
IPAddress[] addr = ipEntry.AddressList;

for (int i = 0; i < addr.Length; i++)
{
    Console.WriteLine("IP Address {0}: {1} ", i, addr[i].ToString());
}
Console.ReadLine();

В этом примере я получаю несколько IP-адресов, но меня интересует только тот, который маршрутизатор назначает компьютеру, на котором запущена программа: IP-адрес, который я бы дал кому-то, если он хочет получить доступ к общей папке на моем компьютере для пример.

Если я не подключен к сети и подключен к Интернету напрямую через модем без маршрутизатора, я хотел бы получить ошибку. Как узнать, подключен ли мой компьютер к сети с помощью C # и можно ли получить IP-адрес локальной сети?


If I am not connected to a network and I am connected to the internet Это утверждение кажется противоречивым. Вы пытаетесь выяснить, подключен ли ваш компьютер к частной локальной сети или Интернету?
Энди

4
Так же, как предупреждение: компьютер может иметь более одного IP-интерфейса, например, LAN и WiFi. Если вы привязываете услугу к определенному оборудованию (скажем, к локальной сети), вам нужен IP-адрес локальной сети. В большинстве следующих примеров будет возвращен «первый» или «последний» найденный IP-адрес. Если у вас более 2 IP-адресов, ваша программа может работать 50% времени, в зависимости от случайного порядка, в котором ОС возвращает IP-адреса.
Марк Лаката

@MarkLakata Я думал о той же проблеме. Функция в моем ответе ниже справится с этим. Вы можете указать, какой тип сетевого интерфейса вы хотите IP-адрес.
compman2408

3
Просто FTR, если вы загляните сюда для Unity3D, это Network.player.ipAddress в их API
Fattie

@MarkLakata, строго говоря, «первый» или «последний» IP - это «правильный» IP-адрес, поскольку браузер может использовать любой доступный IP-адрес. Вероятно, хорошей коррекцией должно быть возвращение каждого IP, связанного с машиной.
UncaAlby

Ответы:


457

Чтобы получить локальный IP-адрес:

public static string GetLocalIPAddress()
{
    var host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (var ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            return ip.ToString();
        }
    }
    throw new Exception("No network adapters with an IPv4 address in the system!");
}

Чтобы проверить, подключены вы или нет:

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();


29
не будет работать, если вы используете такие вещи, как виртуальная коробка vm, genymotion и т. д.
PauLEffect

5
Согласитесь с PaulEffect. Этот метод не только плох для нескольких сетевых карт, но и не различает адреса IP v6 и IP v4.
Макс

16
@John AddressFamily.InterNetwork - это IP v4, а AddressFamily.InterNetworkV6 - это IP v6
Леонардо Ксавье,

Я использую Geraldo H Answer, но если кто-то использует это, вы можете удалить все ips, заканчивающиеся на 1, поэтому он удалит loopback и ips по умолчанию для virtualbox / vmware
Леонардо Ксавье

6
Кажется, вы используете VMWare или другое программное обеспечение для виртуализации. ФП не просила об этом, поэтому я думаю, что голосование из-за этого является довольно резким. Если у вас есть VMWare или несколько сетевых карт, некоторые другие ответы уже дают подсказки для этого.
Mrchief

218

Существует более точный способ, когда на локальном компьютере доступны несколько IP-адресов. ConnectUDP-сокет и считайте его локальную конечную точку:

string localIP;
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
    socket.Connect("8.8.8.8", 65530);
    IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
    localIP = endPoint.Address.ToString();
}

Connectна UDP-сокете имеет следующий эффект: он устанавливает пункт назначения для Send/ Recv, отбрасывает все пакеты с других адресов и - что мы и используем - переводит сокет в «подключенное» состояние, устанавливает соответствующие поля. Это включает в себя проверку наличия маршрута к пункту назначения в соответствии с таблицей маршрутизации системы и соответствующей настройкой локальной конечной точки. Последняя часть, кажется, официально не документирована, но выглядит как неотъемлемая черта API сокетов Беркли (побочный эффект состояния UDP «подключен»), который надежно работает как в Windows, так и в Linux в разных версиях и дистрибутивах.

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


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

10
Без сетевого подключения - у вас нет IP-адреса. Следовательно, код по-прежнему считается действительным, хотя было бы разумно добавить try..catch для обработки такой ситуации и вернуть что-то вроде «127.0.0.1», если было выдано исключение SocketException.
Расс

2
@PatrickSteele, да, он возвращает предпочтительный исходящий IP-адрес для конкретной цели. если вы хотите получить IP-адрес вашей локальной сети, попробуйте указать целевой IP-адрес для вашей локальной сети
Mr.Wang из Next Door

2
Этот метод работает на Mac с ядром dotnet, тогда как принятый ответ в настоящее время - нет.
пеллеты

9
Это решение работает примерно в 4 раза быстрее, чем принятый ответ (Mrchief). Это должен быть реальный ответ
Камарей

115

Рефакторинг кода Mrcheif для использования Linq (т.е. .Net 3.0+). ,

private IPAddress LocalIPAddress()
{
    if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
    {
        return null;
    }

    IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());

    return host
        .AddressList
        .FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
}

:)


У меня есть несколько IP-адресов как «Inter Network», и это решение действительно работает и возвращает правильное. Другой из Mrchief просто дает мне последний. Так что на самом деле этот должен быть правильным;)
Keenora Fluffball

26
@KeenoraFluffball - этот дает вам первый, тогда как этот дает вам последний (или наоборот, зависит от того, как составлен список). В любом случае, ни то, ни другое - если вам дано более одного IP-адреса, вам необходимо знать, какую сеть вы используете. Догадываться, принимая первое или последнее, не является правильным решением.
gbjbaanb

Может также хотеть включить AddressFamily.InterNetworkV6
joelsand

возврат нуля, если сеть недоступна, бесполезен, если вам приходится работать и с автономными ПК. Я заменил его на «return IPAddress.Loopback;» что соответствует специальному IP-номеру 127.0.0.1.
Кристиан

109

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

Dns.GetHostEntry(Dns.GetHostName());

Мне это совсем не нравится, потому что он просто получает все адреса, назначенные вашему компьютеру. Если у вас есть несколько сетевых интерфейсов (что почти все компьютеры делают в настоящее время), вы не знаете, какой адрес соответствует какому сетевому интерфейсу. Проведя кучу исследований, я создал функцию для использования класса NetworkInterface и извлечения из него информации. Таким образом, я могу сказать, какой это тип интерфейса (Ethernet, беспроводной, шлейфовый, туннельный и т. Д.), Активен он или нет, и SOOO гораздо больше.

public string GetLocalIPv4(NetworkInterfaceType _type)
{
    string output = "";
    foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
        {
            foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
            {
                if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                {
                    output = ip.Address.ToString();
                }
            }
        }
    }
    return output;
}

Теперь, чтобы получить IPv4-адрес вашего сетевого интерфейса вызова:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Или ваш беспроводной интерфейс:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Если вы попытаетесь получить IPv4-адрес для беспроводного интерфейса, но на вашем компьютере не установлена ​​беспроводная карта, он просто вернет пустую строку. То же самое с интерфейсом Ethernet.

Надеюсь, это поможет кому-то! :-)

РЕДАКТИРОВАТЬ:

Было отмечено (спасибо @NasBanov), что даже несмотря на то, что эта функция позволяет извлекать IP-адрес гораздо лучше, чем Dns.GetHostEntry(Dns.GetHostName())его использование, она не очень хорошо справляется с поддержкой нескольких интерфейсов одного типа или нескольких IP-адресов на одном интерфейсе. , Он вернет только один IP-адрес, когда может быть назначено несколько адресов. Чтобы вернуть ВСЕ из этих назначенных адресов, вы можете просто манипулировать исходной функцией, чтобы всегда возвращать массив вместо одной строки. Например:

public static string[] GetAllLocalIPv4(NetworkInterfaceType _type)
{
    List<string> ipAddrList = new List<string>();
    foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
        {
            foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
            {
                if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
                {
                    ipAddrList.Add(ip.Address.ToString());
                }
            }
        }
    }
    return ipAddrList.ToArray();
}

Теперь эта функция будет возвращать ВСЕ назначенные адреса для определенного типа интерфейса. Теперь, чтобы получить только одну строку, вы можете использовать .FirstOrDefault()расширение, чтобы вернуть первый элемент в массиве, или, если оно пустое, вернуть пустую строку.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();

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

Проблема в том, что вы возвращаете только 1 IP-адрес на интерфейс ... последний IP, foreach.
Нас Банов

@ compman2408 - не соответствует действительности, один интерфейс может иметь несколько IP-адресов, см. en.wikipedia.org/wiki/Multihoming#Variants для всех комбинаций. Очевидным примером является использование обоих IPv4 и IPv6, но в прошлом у меня был один сетевой адаптер, участвующий в нескольких сетях IPv4. Может быть, необычно, но совершенно законно. Например, для Windows см. Windowsnetworking.com/articles-tutorials/windows-2003/…
Нас Банов,

@NasBanov Эта функция настроена только на получение адресов IPv4, поэтому я даже не буду говорить об IPv6 и его текущей бесполезности. Я знаю о множественной адресации как о подключении к нескольким сетям на нескольких интерфейсах, однако никогда не слышал о подключении к нескольким сетям на одном интерфейсе. Даже если кажется, что вы правы в том, что это действительно возможно, <1% людей, использующих свой NIC таким образом, просто должны изменить функцию, чтобы вместо нее возвращать массив.
compman2408

1
Спасибо тебе за это. К вашему сведению, по крайней мере, на .NET 3.5 mono на OSX item.OperationalStatusвсегда возвращается Unknown.
Ган

36

Вот модифицированная версия (от Compman2408), которая работала для меня:

    internal static string GetLocalIPv4(NetworkInterfaceType _type)
    {  // Checks your IP adress from the local network connected to a gateway. This to avoid issues with double network cards
        string output = "";  // default output
        foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces()) // Iterate over each network interface
        {  // Find the network interface which has been provided in the arguments, break the loop if found
            if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
            {   // Fetch the properties of this adapter
                IPInterfaceProperties adapterProperties = item.GetIPProperties();
                // Check if the gateway adress exist, if not its most likley a virtual network or smth
                if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
                {   // Iterate over each available unicast adresses
                    foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                    {   // If the IP is a local IPv4 adress
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {   // we got a match!
                            output = ip.Address.ToString();
                            break;  // break the loop!!
                        }
                    }
                }
            }
            // Check if we got a result if so break this method
            if (output != "") { break; }
        }
        // Return results
        return output;
    }

Вы можете вызвать этот метод, например, как:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

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


2
Умное решение. Я сейчас использую это.
RQDQ

4
Имеет ту же проблему, что и код, из которого он был получен: он просто возвращает один из IP-адресов, случайный IP-адрес из многих - который не обязательно должен быть тем, который вам нужен. Это зарабатывает ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award
Нас Банов

1
@NasBanov, конечно, я заработал, как я заявляю в своем посте: «который работал для меня». :-)
Gerardo H

Это путь, спасибо за это. Если у вас установлены переключатели обратной связи для эмуляторов, все остальные варианты не будут работать, пока этот не удастся!
DiamondDrake

1
Почему вы возвращаете только последний найденный IP-адрес, а не первый? Симпель breakв самом внутреннем ifили returnв подвале.
Мартин Малдер

20

Это лучший код, который я нашел для получения текущего IP-адреса, избегая получения хоста VMWare или другого неверного IP-адреса.

public string GetLocalIpAddress()
{
    UnicastIPAddressInformation mostSuitableIp = null;

    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

    foreach (var network in networkInterfaces)
    {
        if (network.OperationalStatus != OperationalStatus.Up)
            continue;

        var properties = network.GetIPProperties();

        if (properties.GatewayAddresses.Count == 0)
            continue;

        foreach (var address in properties.UnicastAddresses)
        {
            if (address.Address.AddressFamily != AddressFamily.InterNetwork)
                continue;

            if (IPAddress.IsLoopback(address.Address))
                continue;

            if (!address.IsDnsEligible)
            {
                if (mostSuitableIp == null)
                    mostSuitableIp = address;
                continue;
            }

            // The best IP is the IP got from DHCP server
            if (address.PrefixOrigin != PrefixOrigin.Dhcp)
            {
                if (mostSuitableIp == null || !mostSuitableIp.IsDnsEligible)
                    mostSuitableIp = address;
                continue;
            }

            return address.Address.ToString();
        }
    }

    return mostSuitableIp != null 
        ? mostSuitableIp.Address.ToString()
        : "";
}

Вы, вероятно, должны объяснить, почему этот код является решением для ответа. Можете ли вы получить ответ на вопрос, если вы подключены к Интернету и приводит ли это к ошибке?
Филипп М

Другие способы не используют проверку IsDnsElitable и PrefixOrigin.
rodcesar.santos

@PhilippM Если адрес не подходит для DNS, это зарезервированный внутренний IP-адрес. Это не хост интернет-провайдера. И если PrefixOrigin был предоставлен сервером DHCP, возможно, это лучший выбор адреса. Это уникальная функция, которая работает для меня!
rodcesar.santos

1
@ user1551843 - это было здорово, спасибо. Я использовал старый устаревший метод GetHostByName, но он возвращал IP-адрес адаптера VMWare :)
Джейсон Ньюленд

Это было единственное решение, которое работало для меня по беспроводной сети vpn +. Спасибо.
Jay-опасность

12

Я думаю, что использовать LinQ проще:

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()

14
Это не LINQ, это методы расширения и лямбды. Есть разница
Марк

10
@Mark - если вы не добавите «using System.Linq;» Вы не можете использовать метод «Первый», хотя
BornToCode

5
Это потому, что метод расширения находится в классе Enumerable, который находится в пространстве имен System.Linq. Это все еще не LINQ.
Mark

20
Марк, даже в этой краткой форме, оператор действительно использует LINQ-to-объекты, представленные с синтаксисом метода (лямбда). Синтаксис запроса - это просто синтаксический сахар, который компилируется в цепочку вызовов метода расширения IEnumerable, что и есть LINQ-to-objects. Источники: автор поставщика LINQ-to-SQL и серии статей на эту тему.
константин г


9

Для смеха подумал, что я попытаюсь получить один оператор LINQ, используя новый условный оператор C # 6. Выглядит довольно сумасшедшим и, вероятно, ужасно неэффективно, но это работает.

private string GetLocalIPv4(NetworkInterfaceType type = NetworkInterfaceType.Ethernet)
{
    // Bastardized from: http://stackoverflow.com/a/28621250/2685650.

    return NetworkInterface
        .GetAllNetworkInterfaces()
        .FirstOrDefault(ni =>
            ni.NetworkInterfaceType == type
            && ni.OperationalStatus == OperationalStatus.Up
            && ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null
            && ni.GetIPProperties().UnicastAddresses.FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork) != null
        )
        ?.GetIPProperties()
        .UnicastAddresses
        .FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork)
        ?.Address
        ?.ToString()
        ?? string.Empty;
}

Логика предоставлена Gerardo H(и по ссылке compman2408).


Определенно весело (+1), но на самом деле вовсе не обязательно быть неэффективным. Напоминает мне о программировании в LISP или Forth :-)
Роланд

6

Другой способ получить IP используя выражение linq:

public static List<string> GetAllLocalIPv4(NetworkInterfaceType type)
{
    return NetworkInterface.GetAllNetworkInterfaces()
                   .Where(x => x.NetworkInterfaceType == type && x.OperationalStatus == OperationalStatus.Up)
                   .SelectMany(x => x.GetIPProperties().UnicastAddresses)
                   .Where(x => x.Address.AddressFamily == AddressFamily.InterNetwork)
                   .Select(x => x.Address.ToString())
                   .ToList();
}

5

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

public static string localIPAddress()
{
    IPHostEntry host;
    string localIP = "";
    host = Dns.GetHostEntry(Dns.GetHostName());

    foreach (IPAddress ip in host.AddressList)
    {
        localIP = ip.ToString();

        string[] temp = localIP.Split('.');

        if (ip.AddressFamily == AddressFamily.InterNetwork && temp[0] == "192")
        {
            break;
        }
        else
        {
            localIP = null;
        }
    }

    return localIP;
}

2
Вы имеете в виду Logmein Hamachi? Это решение VPN, и оно работает с сетевым стеком. Кроме того, будучи VPN, кажется разумным, что он возвращает назначенный VPN IP при подключении (только мое предположение).
Mrchief

2
Абсолютно ненадежный. Мало того, что это 192.0.0.0/8не правильный тест для частного IP-адреса (есть 3 диапазона, все отличные от этого), это вполне может быть диапазон корпоративной сети, поэтому не такой уж «локальный».
ivan_pozdeev

5

Протестировано с одной или несколькими сетевыми картами и виртуальными машинами

public static string DisplayIPAddresses()
    {
        string returnAddress = String.Empty;

        // Get a list of all network interfaces (usually one per network card, dialup, and VPN connection)
        NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface network in networkInterfaces)
        {
            // Read the IP configuration for each network
            IPInterfaceProperties properties = network.GetIPProperties();

            if (network.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
                   network.OperationalStatus == OperationalStatus.Up &&
                   !network.Description.ToLower().Contains("virtual") &&
                   !network.Description.ToLower().Contains("pseudo"))
            {
                // Each network interface may have multiple IP addresses
                foreach (IPAddressInformation address in properties.UnicastAddresses)
                {
                    // We're only interested in IPv4 addresses for now
                    if (address.Address.AddressFamily != AddressFamily.InterNetwork)
                        continue;

                    // Ignore loopback addresses (e.g., 127.0.0.1)
                    if (IPAddress.IsLoopback(address.Address))
                        continue;

                    returnAddress = address.Address.ToString();
                    Console.WriteLine(address.Address.ToString() + " (" + network.Name + " - " + network.Description + ")");
                }
            }
        }

       return returnAddress;
    }

Имейте в виду, что этот работает только для Ethernet. Снимите ограничение NetworkInterfaceType для поддержки Wi-Fi.
scor4er

3

Просто моя обновленная версия с использованием LINQ:

/// <summary>
/// Gets the local Ipv4.
/// </summary>
/// <returns>The local Ipv4.</returns>
/// <param name="networkInterfaceType">Network interface type.</param>
IPAddress GetLocalIPv4(NetworkInterfaceType networkInterfaceType)
{
    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType == networkInterfaceType && i.OperationalStatus == OperationalStatus.Up);

    foreach (var networkInterface in networkInterfaces)
    {
        var adapterProperties = networkInterface.GetIPProperties();

        if (adapterProperties.GatewayAddresses.FirstOrDefault() == null)
                continue;
        foreach (var ip in networkInterface.GetIPProperties().UnicastAddresses)
        {
            if (ip.Address.AddressFamily != AddressFamily.InterNetwork)
                    continue;

            return ip.Address;
        }
    }

    return null;
}

2

Предварительные условия: необходимо добавить ссылку на System.Data.Linq и сослаться на нее

using System.Linq;
string ipAddress ="";
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork));

2

Я также боролся с получением правильного IP.

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

Это то, что сработало для меня, надеюсь, это поможет ...

var firstAddress = (from address in NetworkInterface.GetAllNetworkInterfaces().Select(x => x.GetIPProperties()).SelectMany(x => x.UnicastAddresses).Select(x => x.Address)
                    where !IPAddress.IsLoopback(address) && address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork
                    select address).FirstOrDefault();

Console.WriteLine(firstAddress);

1
string str="";

System.Net.Dns.GetHostName();

IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(str);

IPAddress[] addr = ipEntry.AddressList;

string IP="Your Ip Address Is :->"+ addr[addr.Length - 1].ToString();

str всегда пусто
aj.toulan

1

Имейте в виду, что в общем случае у вас может быть несколько трансляций NAT и несколько серверов DNS, каждый из которых работает на разных уровнях трансляции NAT.

Что если у вас есть операторский класс NAT и вы хотите общаться с другими клиентами того же оператора? В общем случае вы точно не знаете, потому что вы можете появляться с разными именами хостов при каждом преобразовании NAT.


1

Устаревший ушел, это работает для меня

public static IPAddress GetIPAddress()
{ 
 IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
 address.AddressFamily == AddressFamily.InterNetwork).First();
 return ip;
}

1

Обновив ответ Mrchief с помощью Linq, мы получим:

public static IPAddress GetLocalIPAddress()
{
   var host = Dns.GetHostEntry(Dns.GetHostName());
   var ipAddress= host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
   return ipAddress;
}

1

Это возвращает адреса от любых интерфейсов, которые имеют адреса шлюза и адреса одноадресной рассылки в двух отдельных списках, IPV4 и IPV6.

public static (List<IPAddress> V4, List<IPAddress> V6) GetLocal()
{
    List<IPAddress> foundV4 = new List<IPAddress>();
    List<IPAddress> foundV6 = new List<IPAddress>();

    NetworkInterface.GetAllNetworkInterfaces().ToList().ForEach(ni =>
    {
        if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null)
        {
            ni.GetIPProperties().UnicastAddresses.ToList().ForEach(ua =>
            {
                if (ua.Address.AddressFamily == AddressFamily.InterNetwork) foundV4.Add(ua.Address);
                if (ua.Address.AddressFamily == AddressFamily.InterNetworkV6) foundV6.Add(ua.Address);
            });
        }
    });

    return (foundV4.Distinct().ToList(), foundV6.Distinct().ToList());
}

Опрятное решение :)
Йохан Франзен

1

Ответов уже много, но я все еще добавляю свой:

public static IPAddress LocalIpAddress() {
    Func<IPAddress, bool> localIpPredicate = ip =>
        ip.AddressFamily == AddressFamily.InterNetwork &&
        ip.ToString().StartsWith("192.168"); //check only for 16-bit block
    return Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(localIpPredicate);
}

Один лайнер:

public static IPAddress LocalIpAddress() => Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.ToString().StartsWith("192.168"));

примечание: выполняйте поиск с последнего, потому что он все еще работал после добавления в устройство некоторых интерфейсов, таких как MobileHotspot, VPN или других модных виртуальных адаптеров.


1
Итак, если мой локальный IP-адрес 10.0.2.3, он не найден? Это действительно странно в этом коде.
франхоммеры

Было сказано, что @frankhommers проверяют только 16-битный блок
nyconing

16-битные блоки также могут быть чем-то еще, кроме 192.168
frankhommers

0

Кроме того, просто код для получения Client Ip:

        public static string getclientIP()
        {
            var HostIP = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "";
            return HostIP;
        }

Надеюсь, это поможет вам.


0
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].MapToIPv4() //returns 192.168.14.1

введите описание изображения здесь


5
Ваш ответ должен содержать описание того, как это работает для случая OP, а также для будущих читателей.
Ронак Дхут

Лучше включить объяснение вашего ответа для будущих читателей.
Николя Жерве

0

Модифицированный код compman2408 для возможности перебора каждого из них NetworkInterfaceType.

public static string GetLocalIPv4 (NetworkInterfaceType _type) {
    string output = null;
    foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces ()) {
        if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up) {
            foreach (UnicastIPAddressInformation ip in item.GetIPProperties ().UnicastAddresses) {
                if (ip.Address.AddressFamily == AddressFamily.InterNetwork) {
                    output = ip.Address.ToString ();
                }
            }
        }
    }
    return output;
}

И вы можете назвать это так:

static void Main (string[] args) {
    // Get all possible enum values:
    var nitVals = Enum.GetValues (typeof (NetworkInterfaceType)).Cast<NetworkInterfaceType> ();

    foreach (var nitVal in nitVals) {
        Console.WriteLine ($"{nitVal} => {GetLocalIPv4 (nitVal) ?? "NULL"}");
    }
}

0
Imports System.Net
Imports System.Net.Sockets
Function LocalIP()
    Dim strHostName = Dns.GetHostName
    Dim Host = Dns.GetHostEntry(strHostName)
    For Each ip In Host.AddressList
        If ip.AddressFamily = AddressFamily.InterNetwork Then
            txtIP.Text = ip.ToString
        End If
    Next

    Return True
End Function

Ниже того же действия

Функция LocalIP ()

Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString

txtIP.Text = Host

Верните Истину

Конечная функция


Ниже приведен пример того же действия. Функция LocalIP () Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString txtIP.Text = Host Return True End Function
YongJae Ким

-2
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1]

одна строка кода: D


7
В некоторых случаях это может вызвать исключение OutOfRangeException.
Луденвье

5
Кроме того, как вы знаете, какой вы хотите? Что правильно для вас, может быть неправильно для кого-то еще.
Марк

-3

Если у вас есть виртуальные машины или дополнительные сетевые карты, в списке адресов могут быть и другие значения. Мое предложение состоит в том, чтобы проверить записи списка адресов и распечатать, что подходит. В моем случае запись 3 была IPv4 адрес моей машины

IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[3];
string ip = ipAddr.ToString();

Не забудьте добавить using System.Net;


1
Коррекция; ВСЕ из них являются IP-адресом вашей машины. Какой из них вы хотите, однако, это совсем другая история. Обратите внимание, что порядок может измениться, и из-за метода, который вы используете, вы всегда будете угадывать.
Марк

Это то, что я сказал, вы должны проверить записи списка адресов, и да, это угадывание, но после просмотра всех записей, угадывание не так уж сложно
Bibaswann Bandyopadhyay

Как бы вы узнали, что подходит? Используя решение compman2048, вы, по крайней мере, знаете, к какому интерфейсу привязан.
Отметить

Это решение не работает на моем компьютере, потому что у меня есть 2 интерфейса WLAN, 2 виртуальные машины и 1 эмулятор, поэтому я получил много IP-адресов. Но если вы ищете внутренний адрес, предоставленный маршрутизатором, он будет начинаться с 192 или 172 или 10, вот как я понял
Bibaswann Bandyopadhyay

Если только ваш маршрутизатор не раздает общедоступные IP-адреса, что необычно, но возможно.
Отметить
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.