Отримати локальну 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, але якщо хтось цим користується, ви, можливо, захочете видалити всі ips, які закінчуються символом 1, тому він видалить циклічні версії для iOS і virtualbox / vmware за замовчуванням
Leonardo Xavier

6
Здається, ви використовуєте VMWare або інше програмне забезпечення для віртуалізації. ОП не вимагала цього, тому я вважаю, що голосування через це є трохи суворим. Якщо у вас є VMWare або кілька NIC, деякі інші відповіді вже дають підказки до цього.
Mrchief

218

Існує більш точний спосіб, коли на локальній машині є кілька 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, відкидає всі пакети з інших адрес і - для чого ми використовуємо - переносить сокет у стан "підключення", встановлює відповідні поля. Це включає перевірку існування маршруту до пункту призначення відповідно до таблиці маршрутизації системи та відповідно встановлення локальної кінцевої точки. Остання частина здається офіційно незадокументованою, але виглядає як цілісна ознака API Berkeley sockets (побічний ефект стану "підключеного" UDP), який надійно працює в Windows та Linux у різних версіях та дистрибутивах.

Отже, цей метод дасть локальну адресу, яка використовувалася б для підключення до вказаного віддаленого хоста. Реального зв'язку не встановлено, отже, вказаний віддалений ip може бути недоступним.


4
Це найкраще рішення, яке працювало на мої потреби. У моїй ситуації у мене багато мережевої карти та кілька бездротових з'єднань. Мені потрібно було отримати бажану IP-адресу залежно від того, яке з'єднання було активовано.
Девід

10
Без підключення до мережі - у будь-якому випадку у вас немає IP-адреси. Тому код як і раніше вважається дійсним, хоча було б доцільно додати спробу..catch, щоб впоратися з такою ситуацією, і повернути щось на зразок "127.0.0.1", якщо б SocketException було кинуто.
Russ

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-адрес як "Інтер Мережа", це рішення насправді працює і повертає правильний назад. Інший з Mrchief просто дає мені останнє. Тож насправді цей має бути правильним;)
Кінора Фуффбол

26
@KeenoraFluffball - цей дає вам перший, тоді як цей дає вам останній (або навпаки, залежить від того, як складається список). Так чи інакше, це не так - якщо вам надано більше 1 IP-адреси, вам потрібно знати, яку мережу ви використовуєте. Вгадування, взявши перше чи останнє, не є правильним рішенням.
gbjbaanb

Можна також включити AddressFamily.InterNetworkV6
joelsand

повернення null, якщо мережа недоступна, не корисна, якщо вам також доведеться обробляти автономні ПК. Я замінив його на "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 адресу вашого виклику мережевого інтерфейсу Ethernet:

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, але в минулому у мене був один адаптер Ethernet, який бере участь у декількох мережах IPv4. Незвичайне можливо - все ж цілком законно. Наприклад, для Windows див. Windowsnetworking.com/articles-tutorials/windows-2003/…
Нас Банов

@NasBanov Ця функція налаштована лише для отримання IPv4-адрес, тому я навіть не збираюся говорити про IPv6 та його поточну непотрібність. Мені відомо, що мультихомінг є підключенням до декількох мереж на декількох інтерфейсах, проте ніколи не чув про підключення до декількох мереж в одному інтерфейсі. Хоча вам здається, що ви вірні, що це насправді можливо, <1% людей, які використовують свій NIC таким чином, просто повинні змінити функцію, щоб повернути масив замість цього.
compman2408

1
Дякую за це. FYI, принаймні на .NET 3.5 mono на OSX item.OperationalStatusзавжди повертається Unknown.
gman

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-шлюз. Друга зміна: я додав docstrings та break твердження, щоб зробити цей метод більш ефективним.


2
Розумний розчин. Зараз я цим користуюся.
RQDQ

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

1
@NasBanov, звичайно, я це заробив, як заявляю у своєму дописі: "який працював на мене". :-)
Джерардо Н

Це шлях, дякую за це. Якщо у вас встановлені зворотні перемикачі циклу для емуляторів, всі інші варіанти виходять з ладу, поки цей успішний!
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()
        : "";
}

Вам, мабуть, слід пояснити, чому саме цей код є рішенням для відповіді. Чи можете ви насправді отримати відповідь на запитання, якщо ви підключені до Інтернету і це призводить до помилки?
Філіпп М

Інші способи не використовують перевірку IsDnsEligible та PrefixOrigin.
rodcesar.santos

@PhilippM Якщо адреса не відповідає DNS, це - зарезервований внутрішній IP. Це не хостинг-провайдер. І якщо PrefixOrigin був застосований сервером DHCP, можливо, це найкращий вибір адреси. Це унікальна функція, яка працює на мене!
rodcesar.santos

1
@ user1551843 - це було чудово, дякую. Я використовував старий метод знеціненого GetHostByName, але він повертав IP адаптера VMWare :)
Джейсон Ньюленд

Це єдине рішення, яке працювало для мене на vpn + wireless. Дякую.
джей-небезпека

12

Я думаю, що використовувати LinQ простіше:

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

14
Це не LINQ, це методи розширення та лямбда. Є різниця.
Марк

10
@Mark - Якщо ви не додаєте "за допомогою System.Linq;" Ви не можете скористатися методом розширення "Перший"
BornToCode

5
Це тому, що метод розширення знаходиться в класі Enumerable, який знаходиться в просторі імен System.Linq. Це все ще не LINQ.
Марк

20
Позначте, навіть у цій короткій формі висловлювання справді використовує LINQ-об'єкти, представлені синтаксисом методу (лямбда). Синтаксис запитів - це просто синтаксичний цукор, який збирається до ланцюжка викликів методу розширення IEnumerable, який є LINQ-до-об'єктів. Джерела: автор провайдера LINQ до 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 :-)
Roland

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
Ви маєте на увазі Логмейн Хамачі? Це рішення 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
франкхоммери

0

Крім того, просто простий код для отримання 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
Ваша відповідь повинна містити опис того, як це працює у випадку з ОП, а також для майбутніх читачів.
Ronak Dhoot

Краще включити пояснення своєї відповіді для майбутніх читачів.
Ніколя Жерве

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 = Хост

Повернення правдиве

Кінцева функція


Нижче наведено приклад цієї ж дії Function LocalIP () Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString txtIP.Text = Повернення хосту True End Function
YongJae Kim

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