Uzyskaj lokalny adres IP

301

W Internecie jest kilka miejsc, które pokazują, jak uzyskać adres IP. I wiele z nich wygląda jak ten przykład:

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

W tym przykładzie otrzymuję kilka adresów IP, ale interesuje mnie tylko ten, który router przypisuje do komputera z programem: adres IP, który dałbym komuś, jeśli chce uzyskać dostęp do folderu współdzielonego na moim komputerze instancja.

Jeśli nie mam połączenia z siecią i jestem podłączony do Internetu bezpośrednio przez modem bez routera, chciałbym otrzymać błąd. Jak mogę sprawdzić, czy mój komputer jest podłączony do sieci za pomocą C # i czy tak jest, aby uzyskać adres IP LAN.

Tono Nam
źródło
If I am not connected to a network and I am connected to the internet To stwierdzenie wydaje się sprzeczne. Czy próbujesz dowiedzieć się, czy komputer jest podłączony do prywatnej sieci LAN czy Internetu?
Andy,
4
Tylko jako ostrzeżenie: komputer może mieć więcej niż jeden interfejs IP, na przykład sieć LAN i WiFi. Jeśli powiążesz usługę z określonym sprzętem (np. LAN), potrzebujesz adresu IP sieci LAN. Większość poniższych przykładów zwróci znaleziony „pierwszy” lub „ostatni” adres IP. Jeśli masz więcej niż 2 adresy IP, Twój program może działać 50% czasu, w zależności od losowej kolejności, w której system zwraca adresy IP.
Mark Lakata
@MarkLakata Myślałem o tym samym problemie. Funkcja w mojej odpowiedzi poniżej sobie z tym poradzi. Możesz określić, z jakiego typu interfejsu sieciowego chcesz uzyskać adres IP.
compman2408
3
Po prostu FTR, jeśli google tutaj dla Unity3D, to Network.player.ipAdres w ich API
Fattie
@ MarkLakata ściśle mówiąc, „pierwszy” lub „ostatni” adres IP to „poprawny” adres IP, ponieważ przeglądarka może korzystać z dowolnego dostępnego adresu IP. Prawdopodobnie dobrą korektą powinno być zwracanie każdego adresu IP związanego z maszyną.
UncaAlby

Odpowiedzi:

457

Aby uzyskać lokalny adres 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!");
}

Aby sprawdzić, czy masz połączenie czy nie:

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

Mrchief
źródło
29
nie będzie działać, jeśli użyjesz rzeczy takich jak vm virtual box, genymotion itp.
PauLEffect
5
Zgadzam się z PaulEffect. Ta metoda jest nie tylko zła dla wielu kart sieciowych, ale także nie rozróżnia adresów IP v6 i IP v4.
Maks.
16
@John AddressFamily.InterNetwork to IP v4, a AddressFamily.InterNetworkV6 to IP v6
Leonardo Xavier
Korzystam z Geraldo H Answer, ale jeśli ktoś tego używa, możesz usunąć wszystkie ipsy kończące się na 1, więc usunie to loopback i domyślne ips i virtualbox / vmware
Leonardo Xavier
6
Wygląda na to, że używasz VMWare lub innego oprogramowania do wirtualizacji. OP nie poprosił o to, więc uważam, że głosowanie z tego powodu jest nieco trudne. Jeśli masz VMWare lub wiele kart sieciowych, niektóre inne odpowiedzi już dostarczają wskazówek.
Mrchief
218

Istnieje dokładniejszy sposób, gdy na lokalnym komputerze dostępnych jest wiele adresów IP. Connectgniazdo UDP i przeczytaj jego lokalny punkt końcowy:

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

Connectna gnieździe UDP ma następujący efekt: ustawia miejsce docelowe dla Send/ Recv, odrzuca wszystkie pakiety z innych adresów i - właśnie tego używamy - przenosi gniazdo do stanu „połączonego”, ustawia odpowiednie pola. Obejmuje to sprawdzenie istnienia trasy do miejsca docelowego zgodnie z tablicą routingu systemu i odpowiednie ustawienie lokalnego punktu końcowego. Ostatnia część wydaje się być nieudokumentowana oficjalnie, ale wygląda na integralną cechę API gniazd Berkeley (efekt uboczny stanu „podłączonego” UDP), który działa niezawodnie zarówno w systemie Windows, jak i Linux w różnych wersjach i dystrybucjach.

Tak więc ta metoda da adres lokalny, który będzie używany do łączenia się z określonym hostem zdalnym. Nie ustanowiono rzeczywistego połączenia, dlatego określony zdalny adres IP może być nieosiągalny.

Mr.Wang z Next Door
źródło
4
To najlepsze rozwiązanie, które zadziałało na moje potrzeby. W mojej sytuacji mam wiele kart sieciowych i kilka połączeń bezprzewodowych. Musiałem uzyskać preferowany adres IP w zależności od tego, które połączenie zostało aktywowane.
David
10
Bez połączenia sieciowego - w każdym razie nie masz adresu IP. Dlatego kod nadal jest ważny, choć rozsądnie byłoby dodać try..catch, aby poradzić sobie z taką sytuacją, i zwrócić coś takiego jak „127.0.0.1”, jeśli zgłoszony zostanie wyjątek SocketException.
Russ
2
@PatrickSteele, tak, zwraca preferowany wychodzący adres IP dla określonego celu. jeśli chcesz uzyskać adres IP swojej sieci LAN, spróbuj wskazać, że celem jest adres IP z sieci LAN
Mr.Wang z Next Door
2
Ta metoda działa na komputerze Mac z rdzeniem dotnet, podczas gdy obecnie akceptowana odpowiedź nie.
Pellet
9
To rozwiązanie działa około 4 razy szybciej niż zaakceptowana odpowiedź (Mrchief). To powinna być prawdziwa odpowiedź
Kamarey
115

Refaktoryzacja kodu Mrcheifa w celu wykorzystania Linq (tj. .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);
}

:)

Pure.Krome
źródło
Mam kilka adresów IP jako „Inter Network”, a to rozwiązanie faktycznie działa i zwraca właściwy. Drugi z Mrchief daje mi tylko ostatni. Tak właściwie to ten powinien być właściwy;)
Keenora Fluffball
26
@KeenoraFluffball - ten daje ci pierwszy, podczas gdy ten daje ci ostatni (lub odwrotnie, zależy od tego, jak tworzona jest lista). Tak czy inaczej, żadna nie jest właściwa - jeśli otrzymałeś więcej niż 1 adres IP, musisz wiedzieć, z której sieci korzystasz. Zgadywanie na podstawie pierwszego lub ostatniego nie jest właściwym rozwiązaniem.
gbjbaanb
Może chcieć również dołączyć AddressFamily.InterNetworkV6
joelsand
Zwrócenie wartości NULL, jeśli sieć nie jest dostępna, nie jest przydatne, jeśli trzeba również obsługiwać samodzielne komputery. Zamieniłem go na „return IPAddress.Loopback;” co odpowiada specjalnemu numerowi IP 127.0.0.1.
Christian
109

Wiem, że to może kopać martwego konia, ale może to komuś pomóc. Wszędzie szukałem sposobu na znalezienie mojego lokalnego adresu IP, ale wszędzie tam jest napisane, aby użyć:

Dns.GetHostEntry(Dns.GetHostName());

W ogóle mi się to nie podoba, ponieważ po prostu dostaje wszystkie adresy przypisane do twojego komputera. Jeśli masz wiele interfejsów sieciowych (które robią obecnie prawie wszystkie komputery), nie masz pojęcia, który adres pasuje do którego interfejsu sieciowego. Po przeprowadzeniu wielu badań stworzyłem funkcję, aby użyć klasy NetworkInterface i wyciągnąć z niej informacje. W ten sposób mogę powiedzieć, jaki to jest interfejs (Ethernet, bezprzewodowy, pętla zwrotna, tunel itp.), Czy jest aktywny czy nie, i SOOO znacznie więcej.

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

Teraz, aby uzyskać adres IPv4 połączenia z interfejsem sieci Ethernet:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Lub twój interfejs bezprzewodowy:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Jeśli spróbujesz uzyskać adres IPv4 dla interfejsu bezprzewodowego, ale twój komputer nie ma zainstalowanej karty bezprzewodowej, zwróci tylko pusty ciąg. To samo z interfejsem Ethernet.

Mam nadzieję, że to komuś pomoże! :-)

EDYTOWAĆ:

Zwrócono uwagę (dzięki @NasBanov), że chociaż ta funkcja zajmuje się wyodrębnianiem adresu IP w znacznie lepszy sposób niż używanie Dns.GetHostEntry(Dns.GetHostName())go, nie radzi sobie dobrze z obsługą wielu interfejsów tego samego typu lub wielu adresów IP na jednym interfejsie . Zwróci tylko jeden adres IP, gdy może być przypisanych wiele adresów. Aby zwrócić WSZYSTKIE przypisane adresy, wystarczy manipulować oryginalną funkcją, aby zawsze zwracała tablicę zamiast pojedynczego łańcucha. Na przykład:

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

Teraz ta funkcja zwróci WSZYSTKIE przypisane adresy dla określonego typu interfejsu. Teraz, aby uzyskać tylko jeden ciąg, możesz użyć .FirstOrDefault()rozszerzenia, aby zwrócić pierwszy element w tablicy lub, jeśli jest pusty, zwrócić pusty ciąg.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
compman2408
źródło
5
Jest to lepsze rozwiązanie, ponieważ w wielu miejscach nie ma użyteczności DNS, a interfejsy mogą mieć wiele adresów IP. Korzystam również z podobnej metody.
Mert Gülsoy
Problem polega na tym, że zwracasz tylko 1 adres IP na interfejs ... ostatnie IP, foreach.
Nas Banov
@ compman2408 - nieprawda, jeden interfejs może mieć wiele adresów IP, patrz en.wikipedia.org/wiki/Multihoming#Variants dla wszystkich kombinacji. Oczywistym przykładem jest uruchomienie zarówno IPv4, jak i IPv6, ale w przeszłości miałem pojedynczy adapter Ethernet, który uczestniczył w wielu sieciach IPv4. Może niezwykłe - ale całkowicie legalne. Np. Dla Windows patrz windowsnetworking.com/articles-tutorials/windows-2003/…
Nas Banov
@NasBanov Ta funkcja jest skonfigurowana tylko w celu uzyskania adresów IPv4, więc nawet nie będę mówić o IPv6 i jego aktualnej bezużyteczności. Zdaję sobie sprawę z tego, że multihoming łączy się z wieloma sieciami na wielu interfejsach, jednak nigdy nie słyszałem o łączeniu się z wieloma sieciami na tym samym interfejsie. Nawet jeśli wydaje się, że masz rację, że jest to rzeczywiście możliwe, <1% osób korzystających w ten sposób z karty sieciowej musiałoby po prostu zmienić funkcję, aby zamiast tego zwrócić tablicę.
compman2408
1
Dziękuję Ci za to. Do Twojej wiadomości, przynajmniej na mono .NET 3.5 mono w OSX item.OperationalStatuszawsze zwraca Unknown.
gman
36

Oto zmodyfikowana wersja (z wersji compman2408), która działała dla mnie:

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

Możesz wywołać tę metodę na przykład:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Zmiana: pobieram adres IP z adaptera, do którego przypisano adres IP bramy. Druga zmiana: dodałem dokumenty i instrukcję break, aby ta metoda była bardziej wydajna.

Gerardo H.
źródło
2
Sprytne rozwiązanie. Teraz tego używam.
RQDQ,
4
Ma ten sam problem, co kod, z którego został uzyskany: po prostu zwraca jeden z adresów IP, losowy adres IP z wielu - który nie musi być tym, którego potrzebujesz. Zarabia ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award
Nas Banov
1
@NasBanov, Jasne, że na to zasłużyłem, pisząc w poście: „które dla mnie zadziałało”. :-)
Gerardo H
To jest ta droga, dziękuję za to. Kiedy masz zainstalowane przełączniki pętli zwrotnej dla emulatorów, wszystkie inne warianty zawodzą, a ten się powiedzie!
DiamondDrake
1
Dlaczego zwracasz tylko ostatni znaleziony adres IP, a nie pierwszy? Simpel breakw najbardziej wewnętrznej iflub returnzrobiłby lewę.
Martin Mulder,
20

To najlepszy kod, jaki znalazłem, aby uzyskać bieżący adres IP, unikając hosta VMWare lub innego nieprawidłowego adresu 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()
        : "";
}
rodcesar.santos
źródło
Prawdopodobnie powinieneś wyjaśnić, dlaczego ten kod jest rozwiązaniem dla odpowiedzi. Czy naprawdę możesz uzyskać odpowiedź na pytanie, jeśli masz połączenie z Internetem i czy powoduje to błąd?
Philipp M
Inne sposoby nie wykorzystują sprawdzania poprawności IsDnsEligible i PrefixOrigin.
rodcesar.santos,
@PhilippM Jeśli adres nie jest adresem DNS spełniającym kryteria, jest to wewnętrzny adres IP zastrzeżony. To nie jest host dostawcy Internetu. A jeśli PrefixOrigin został dostarczony przez serwer DHCP, możliwe, że jest to najlepszy wybór adresu. To jest wyjątkowa funkcja, która działa na mnie!
rodcesar.santos,
1
@ user1551843 - to było świetne, dzięki. Używałem starej, nieaktualnej metody GetHostByName, ale zwracała ona adres IP adaptera VMWare :)
Jason Newland
To było jedyne rozwiązanie, które działało dla mnie na VPN + Wireless. Dziękuję Ci.
jay-
12

Myślę, że korzystanie z LinQ jest łatwiejsze:

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()
Kapé
źródło
14
To nie jest LINQ, to metody rozszerzenia i lambda. Jest różnica.
Mark
10
@Mark - Jeśli nie dodasz „using System.Linq;” nie można jednak użyć metody rozszerzenia „Pierwsza”
BornToCode,
5
Jest tak, ponieważ metoda rozszerzenia znajduje się w klasie Enumerable, która znajduje się w przestrzeni nazw System.Linq. To wciąż nie jest LINQ.
Mark
20
Zaznacz, nawet w tej krótkiej formie, instrukcja faktycznie używa LINQ-do-obiektów przedstawionych ze składnią metody (lambda). Składnia zapytania to po prostu cukier składniowy, który jest kompilowany do łańcucha wywołań rozszerzających IEnumerable, którym jest LINQ-to-objects. Źródła: autor dostawcy LINQ-to-SQL i serii artykułów na ten temat.
Constantine g
9

Dla śmiechu, pomyślałem, że spróbuję uzyskać pojedynczą instrukcję LINQ za pomocą nowego operatora warunkowego C # 6. Wygląda na dość szalonego i prawdopodobnie okropnie nieefektywnego, ale działa.

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

Logika dzięki uprzejmości Gerardo H(i przez odniesienie compman2408).

Stajs
źródło
Zdecydowanie fajne (+1), ale tak naprawdę wcale nie musi być nieefektywne. Przypomina mi programowanie w LISP lub Forth :-)
Roland
6

Inny sposób uzyskania adresu IP za pomocą wyrażenia 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();
}
Amirhossein Yari
źródło
5

@mrcheif Znalazłem tę odpowiedź dzisiaj i była bardzo przydatna, chociaż zwróciła zły adres IP (nie z powodu niedziałającego kodu), ale dała zły adres IP sieci, gdy masz takie rzeczy jak 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;
}
Jordan Trainor
źródło
2
Masz na myśli Logmein Hamachi? Jest to rozwiązanie VPN i majstruje przy stosie sieciowym. Ponadto, będąc VPN, wydaje się rozsądne, że zwraca VPN przypisane IP po podłączeniu (tylko zgaduję).
Mrchief 28.01.13
2
Całkowicie zawodny. Nie tylko 192.0.0.0/8nie jest to poprawny test prywatnego adresu IP (istnieją 3 zakresy, wszystkie inne od tego), może to być również zasięg sieci korporacyjnej, więc nie tyle „lokalny”.
ivan_pozdeev
5

Testowany z jedną lub wieloma kartami LAN i maszynami wirtualnymi

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;
    }
Shanewaj
źródło
Pamiętaj, że ten działa tylko dla Ethernetu. Usuń ograniczenie NetworkInterfaceType, aby obsługiwać Wi-Fi.
scor4er,
3

Tylko zaktualizowana wersja mojego przy użyciu 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;
}
Giusepe
źródło
2

Wymagania wstępne: musisz dodać odwołanie System.Data.Linq i odwołać się do niego

using System.Linq;
string ipAddress ="";
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork));
pola
źródło
2

Miałem również problemy z uzyskaniem poprawnego adresu IP.

Wypróbowałem tutaj różne rozwiązania, ale żadne nie zapewniło mi pożądanego efektu. Prawie wszystkie dostarczone testy warunkowe nie spowodowały użycia adresu.

To działało dla mnie, mam nadzieję, że to pomaga ...

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);
UberBiza
źródło
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();
Naimish Mungara
źródło
str jest zawsze pusty
aj.toulan
1

Pamiętaj, że w ogólnym przypadku możesz mieć wiele tłumaczeń NAT i wiele serwerów dns, z których każdy działa na różnych poziomach translacji NAT.

Co zrobić, jeśli masz NAT klasy operatorskiej i chcesz komunikować się z innymi klientami tego samego operatora? W ogólnym przypadku nigdy nie wiadomo na pewno, ponieważ możesz występować z różnymi nazwami hostów przy każdym tłumaczeniu NAT.

sgjsfth sthseth
źródło
1

Przestarzałe odeszło, to działa dla mnie

public static IPAddress GetIPAddress()
{ 
 IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
 address.AddressFamily == AddressFamily.InterNetwork).First();
 return ip;
}
Sourcephy
źródło
1

Aktualizując odpowiedź Mrchiefa za pomocą Linq, będziemy mieli:

public static IPAddress GetLocalIPAddress()
{
   var host = Dns.GetHostEntry(Dns.GetHostName());
   var ipAddress= host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
   return ipAddress;
}
Ashkan Sirous
źródło
1

Zwraca adresy z interfejsów, które mają adresy bram i adresy emisji pojedynczej na dwóch osobnych listach, IPV4 i 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());
}
Michael Jordan
źródło
Dobre rozwiązanie :)
Johan Franzén
1

Jest już wiele odpowiedzi, ale nadal wnoszę swój jeden:

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

Jedna wkładka:

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

Uwaga: Wyszukaj od ostatniego, ponieważ nadal działało po dodaniu niektórych interfejsów do urządzenia, takich jak MobileHotspot, VPN lub innych fantazyjnych kart wirtualnych.

nyconing
źródło
1
Więc jeśli mój lokalny adres IP to 10.0.2.3, nie został znaleziony? To naprawdę dziwne w tym kodzie.
frankhommers
@frankhommers powiedziano, że sprawdź tylko blok 16-bitowy
nyconing
Bloki 16-bitowe mogą być również czymś innym niż
192.168
0

Dodatkowo prosty kod do uzyskania klienta IP:

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

Mam nadzieję, że to ci pomoże.

Majedur Rahaman
źródło
0
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].MapToIPv4() //returns 192.168.14.1

wprowadź opis zdjęcia tutaj

Eran Peled
źródło
5
Twoja odpowiedź powinna zawierać opis tego, jak to działa w przypadku OP, a także dla przyszłych czytelników.
Ronak Dhoot
Lepiej jest dołączyć wyjaśnienie swojej odpowiedzi dla przyszłych czytelników.
Nicolas Gervais
0

Zmodyfikowano kod compman2408, aby móc iterować po każdym z nich 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;
}

Możesz to tak nazwać:

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"}");
    }
}
Najeeb
źródło
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

Poniżej tej samej akcji

Funkcja LocalIP ()

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

txtIP.Text = Host

Return True

Funkcja zakończenia

YongJae Kim
źródło
Poniższy przykład ilustruje tę samą akcję Funkcja LocalIP () Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString txtIP.Text = Funkcja powrotu hosta True End
YongJae Kim
-2
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1]

jeden wiersz kodu: D

Fuzzybear
źródło
7
W niektórych przypadkach może generować wyjątek OutOfRangeException.
Loudenvier
5
Ponadto, skąd wiesz, który chcesz? To, co jest dla ciebie dobre, może być złe dla kogoś innego.
Mark
-3

Jeśli masz maszyny wirtualne lub dodatkowe karty sieciowe, na liście adresów mogą znajdować się inne wartości. Moją propozycją jest sprawdzenie wpisów listy adresowej i wydrukowanie, które są odpowiednie. W moim przypadku pozycja 3 to adres IPv4 mojej maszyny

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

Nie zapomnij dodać using System.Net;

Bibaswann Bandyopadhyay
źródło
1
Korekta; WSZYSTKIE z nich to adres IP urządzenia. Który chcesz, to jednak zupełnie inna historia. Pamiętaj, że kolejność może się zmienić, a ze względu na używaną metodę zawsze będziesz zgadywać.
Mark
Tak powiedziałem, powinieneś sprawdzić wpisy na liście adresów i tak, to zgadywanie, ale po obejrzeniu wszystkich wpisów zgadywanie nie jest trudne
Bibaswann Bandyopadhyay
Skąd wiesz, który jest odpowiedni? Korzystając z rozwiązania compman2048, będziesz przynajmniej wiedział, który jest powiązany z którym interfejsem.
Mark
To rozwiązanie nie działało na moim komputerze, ponieważ mam 2 interfejsy WLAN, 2 maszyny wirtualne i 1 emulator, więc mam dużo adresów IP. Ale jeśli szukasz adresu wewnętrznego dostarczonego przez router, zacznie się on od 192 lub 172 lub 10, tak właśnie zrozumiałem
Bibaswann Bandyopadhyay
Chyba że router rozdaje publiczne adresy IP, co jest rzadkie, ale możliwe.
Mark