Получить локальный 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'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-адрес LAN.

21 ответов


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


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

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


рефакторинг кода Mrcheif для использования Linq(т. е. .Чистая 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-адрес, но везде, где я нахожу его, говорит использовать:

Dns.GetHostEntry(Dns.GetHostName());

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

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();

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

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-адрес шлюза.


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

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

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

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

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

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).


предварительные условия: вы должны добавить систему.Данные.Ссылка Linq и ссылаться на нее

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

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

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

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

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


просто обновленная версия моей, используя 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 (NetworkInterface networkInterface in networkInterfaces)
        {
            var adapterProperties = networkInterface.GetIPProperties();

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

        return null;
    }

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

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

обновление ответа Mrchief с помощью Linq, у нас будет:

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

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

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

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


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

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

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

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


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

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

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

Returns (для этого компьютера): 192.168.0.100 (