Получить локальный 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.