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

В Интернете есть несколько мест, где показано, как получить 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 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-адрес, который я бы предоставил кому-либо, если он хочет получить доступ к общей папке в например, на моем компьютере.

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

Ответ 1

Чтобы получить локальный адрес 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();

Ответ 2

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

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, отбрасывает все пакеты с других адресов, и - то, что мы используем, - передает сокет в "подключенный" state, устанавливает соответствующие поля. Это включает проверку наличия маршрута до места назначения в соответствии с таблицей маршрутизации системы и соответствующим образом назначением локальной конечной точки. Последняя часть кажется официально недокументированной, но она выглядит как неотъемлемая черта API сокетов Berkeley (побочный эффект состояния "подключенного" UDP), который надежно работает в Windows и Linux в версиях и дистрибутивах.

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

Ответ 3

Рефакторинг кода 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);
}

:)

Ответ 4

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

Dns.GetHostEntry(Dns.GetHostName());

Мне это совсем не нравится, потому что он просто получает все адреса, назначенные вашему компьютеру. Если у вас несколько сетевых интерфейсов (которые в значительной степени работают на всех компьютерах в настоящее время), вы не знаете, какой адрес идет с каким сетевым интерфейсом. После выполнения ряда исследований я создал функцию для использования класса NetworkInterface и вытащил из нее информацию. Таким образом, я могу сказать, какой тип интерфейса он (Ethernet, беспроводной, loopback, tunnel и т.д.), Независимо от того, активен он или нет, и 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-адрес вашего сетевого интерфейса Ethernet:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

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

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

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

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

EDIT:

Было отмечено (спасибо @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

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

internal static string GetLocalIPv4(NetworkInterfaceType _type)
{
    string output = "";
    foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
        {
            IPInterfaceProperties adapterProperties = item.GetIPProperties();

            if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
            {
                foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                {
                    if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        output = ip.Address.ToString();
                    }
                }
            }
        }
    }

    return output;
}

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

Ответ 6

Это лучший код, который я нашел, чтобы получить текущий 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()
        : "";
}

Ответ 7

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

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

Ответ 8

Смех, подумал, что я попытаюсь получить один оператор LINQ, используя новый оператор с нулевым условием С# 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).

Ответ 9

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

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;
}

Ответ 10

Другой способ получить 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();
}

Ответ 11

Протестировано с помощью одной или нескольких плат LAN и виртуальных машин

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;
    }

Ответ 12

Предварительные требования: вы должны добавить ссылку 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));

Ответ 13

Я также боролся с получением правильного 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);

Ответ 14

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();

Ответ 15

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

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

Ответ 16

Просто обновленная версия моей версии с использованием 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;
}

Ответ 17

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

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

Ответ 18

Обновляя ответ Mrchief с Linq, мы будем иметь:

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

Ответ 19

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

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

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

Ответ 20

Это возвращает адреса от любых интерфейсов, которые имеют адреса шлюзов и адреса одноадресной рассылки в двух отдельных списках, 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());
}

Ответ 21

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

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 или других модных виртуальных адаптеров.

Ответ 22

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

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

Ответ 23

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

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

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

Ответ 24

Здесь представлен полнофункциональный и надежный 1-лайнер для локального IP-адреса. Сделано с параллельным исполнением языка Dyalog APL. Интересно, что эта небольшая часть кода поддерживает 0, 1 или несколько адаптеров IPv4 - результатом будет только массив с длиной 0, 1 или n вложенных текстовых векторов.

В основном для вашей путаницы, я думаю: -)

#.Dns.(a.AddressFamily.(⎕THIS=InterNetwork)/a←(GetHostEntry GetHostName).AddressList).ToString

Возвращает (для этого компьютера): 192.168.0.100 (< - одноэлементный векторный блок, первый элемент которого представляет собой вектор с 13 символами)