Holen Sie sich die lokale IP-Adresse

301

Im Internet gibt es mehrere Stellen, die Ihnen zeigen, wie Sie eine IP-Adresse erhalten. Und viele von ihnen sehen wie folgt aus:

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

In diesem Beispiel erhalte ich mehrere IP-Adressen, aber ich bin nur daran interessiert, die zu erhalten, die der Router dem Computer zuweist, auf dem das Programm ausgeführt wird: die IP, die ich jemandem geben würde, wenn er auf einen freigegebenen Ordner auf meinem Computer zugreifen möchte Beispiel.

Wenn ich nicht mit einem Netzwerk verbunden bin und über ein Modem ohne Router direkt mit dem Internet verbunden bin, möchte ich eine Fehlermeldung erhalten. Wie kann ich feststellen, ob mein Computer mit C # mit einem Netzwerk verbunden ist und ob dann die LAN-IP-Adresse abgerufen werden soll?

Tono Nam
quelle
If I am not connected to a network and I am connected to the internet Diese Aussage scheint widersprüchlich. Versuchen Sie herauszufinden, ob Ihr Computer mit einem privaten LAN oder dem Internet verbunden ist?
Andy
4
Nur als Warnung: Ein Computer kann mehr als eine IP-Schnittstelle haben, zum Beispiel ein LAN und WiFi. Wenn Sie einen Dienst an eine bestimmte Hardware (z. B. das LAN) binden, benötigen Sie die IP des LAN. Die meisten der folgenden Beispiele geben die gefundene "erste" oder "letzte" IP-Adresse zurück. Wenn Sie mehr als 2 IP-Adressen haben, arbeitet Ihr Programm möglicherweise 50% der Zeit, abhängig von der zufälligen Reihenfolge, in der das Betriebssystem die IP-Adressen zurückgibt.
Mark Lakata
@ MarkLakata Ich dachte an das gleiche Problem. Die Funktion in meiner Antwort unten wird damit umgehen. Sie können angeben, von welcher Art von Netzwerkschnittstelle die IP-Adresse stammen soll.
compman2408
3
Nur FTR, wenn Sie hier für Unity3D googeln, ist es Network.player.ipAddress in ihrer API
Fattie
@MarkLakata streng genommen, die „erste“ oder „letzte“ IP ist die „richtige“ IP, wie der Browser eine beliebige IP verwenden , die verfügbar ist. Eine gute Korrektur sollte wahrscheinlich darin bestehen, jede dem Computer zugeordnete IP zurückzugeben.
UncaAlby

Antworten:

457

So erhalten Sie die lokale IP-Adresse:

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

So überprüfen Sie, ob Sie verbunden sind oder nicht:

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

Mrchief
quelle
29
funktioniert nicht, wenn Sie Dinge wie VM Virtual Box, Genymotion usw. verwenden
PauLEffect
5
Stimmen Sie PaulEffect zu. Diese Methode ist nicht nur für mehrere Netzwerkkarten schlecht, sondern unterscheidet auch nicht zwischen IP v6- und IP v4-Adressen.
Max
16
@ John AddressFamily.InterNetwork ist IP v4 und AddressFamily.InterNetworkV6 ist IP v6
Leonardo Xavier
Ich verwende Geraldo H Antwort, aber wenn jemand dies verwendet, möchten Sie möglicherweise alle IPs entfernen, die mit 1 enden, damit Loopback- und Virtualbox / VMware-Standard-IPs entfernt werden
Leonardo Xavier
6
Anscheinend verwenden Sie VMWare oder eine andere Virtualisierungssoftware. Das OP hat nicht darum gebeten, daher denke ich, dass die Abstimmung aufgrund dessen etwas hart ist. Wenn Sie über VMWare oder mehrere Netzwerkkarten verfügen, geben einige der anderen Antworten bereits Hinweise darauf.
Mrchief
218

Es gibt einen genaueren Weg, wenn auf dem lokalen Computer mehrere IP-Adressen verfügbar sind. Connecteinen UDP-Socket und lesen Sie seinen lokalen Endpunkt:

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

ConnectEin UDP-Socket hat folgenden Effekt: Er legt das Ziel für Send/ fest Recv, verwirft alle Pakete von anderen Adressen und versetzt den Socket - was wir verwenden - in den Status "verbunden" und stellt die entsprechenden Felder ein. Dies umfasst das Überprüfen des Vorhandenseins der Route zum Ziel gemäß der Routing-Tabelle des Systems und das entsprechende Festlegen des lokalen Endpunkts. Der letzte Teil scheint offiziell nicht dokumentiert zu sein, aber es scheint ein integraler Bestandteil der Berkeley-Sockets-API zu sein (ein Nebeneffekt des UDP-Status "verbunden"), der sowohl unter Windows als auch unter Linux über Versionen und Distributionen hinweg zuverlässig funktioniert .

Diese Methode gibt also die lokale Adresse an, die für die Verbindung mit dem angegebenen Remote-Host verwendet wird. Es wurde keine echte Verbindung hergestellt, daher kann die angegebene Remote-IP nicht erreichbar sein.

Mr. Wang von nebenan
quelle
4
Dies ist die beste Lösung, die für meine Bedürfnisse funktioniert hat. In meiner Situation habe ich viele Netzwerkkarten und einige drahtlose Verbindungen. Ich musste die bevorzugte IP-Adresse erhalten, je nachdem, welche Verbindung aktiviert wurde.
David
10
Ohne Netzwerkverbindung haben Sie sowieso keine IP-Adresse. Daher gilt der Code weiterhin als gültig, obwohl es ratsam wäre, einen try..catch hinzuzufügen, um mit einer solchen Situation umzugehen, und etwas wie "127.0.0.1" zurückzugeben, wenn eine SocketException ausgelöst würde.
Russ
2
@PatrickSteele, yep, gibt die bevorzugte ausgehende IP-Adresse für das spezifische Ziel zurück. Wenn Sie Ihre LAN-IP-Adresse erhalten möchten, versuchen Sie, das Ziel anzugeben, das eine IP aus Ihrem LAN sein soll
Mr.Wang von Next Door
2
Diese Methode funktioniert auf einem Mac mit Dotnet-Kern, während die akzeptierte Antwort dies derzeit nicht tut.
Pellet
9
Diese Lösung funktioniert ungefähr viermal schneller als die akzeptierte Antwort (von Mrchief). Dies sollte die wahre Antwort sein
Kamarey
115

Überarbeitung des Mrcheif-Codes zur Nutzung von Linq (dh .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
quelle
Ich habe ein paar IP-Adressen als "Inter Network" und diese Lösung funktioniert tatsächlich und gibt die richtige zurück. Der andere von Mrchief gibt mir nur den letzten. Also eigentlich sollte dieser der richtige sein;)
Keenora Fluffball
26
@KeenoraFluffball - dieser gibt dir den ersten, während dieser dir den letzten gibt (oder umgekehrt, hängt davon ab, wie die Liste aufgebaut ist). In beiden Fällen ist beides nicht richtig. Wenn Ihnen mehr als eine IP-Adresse zugewiesen wurde, müssen Sie wissen, welches Netzwerk Sie verwenden. Das Erraten mit dem ersten oder letzten ist nicht die richtige Lösung.
Gbjbaanb
Vielleicht möchten Sie auch AddressFamily.InterNetworkV6
joelsand
Die Rückgabe von null, wenn das Netzwerk nicht verfügbar ist, ist nicht sinnvoll, wenn Sie auch eigenständige PCs verarbeiten müssen. Ich habe es durch "return IPAddress.Loopback" ersetzt. Dies entspricht der speziellen IP-Nummer 127.0.0.1.
Christian
109

Ich weiß, dass dies ein totes Pferd treten kann, aber vielleicht kann dies jemandem helfen. Ich habe überall nach einer Möglichkeit gesucht, meine lokale IP-Adresse zu finden, aber überall, wo ich sie finde, heißt es:

Dns.GetHostEntry(Dns.GetHostName());

Ich mag das überhaupt nicht, weil es nur alle Adressen erhält, die Ihrem Computer zugewiesen sind. Wenn Sie mehrere Netzwerkschnittstellen haben (was heutzutage so gut wie alle Computer tun), wissen Sie nicht, welche Adresse zu welcher Netzwerkschnittstelle gehört. Nachdem ich einige Nachforschungen angestellt hatte, erstellte ich eine Funktion zur Verwendung der NetworkInterface-Klasse und riss die Informationen heraus. Auf diese Weise kann ich feststellen, um welche Art von Schnittstelle es sich handelt (Ethernet, Wireless, Loopback, Tunnel usw.), ob sie aktiv ist oder nicht, und SOOO viel mehr.

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

So rufen Sie jetzt die IPv4-Adresse Ihres Ethernet-Netzwerkschnittstellenaufrufs ab:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Oder Ihre drahtlose Schnittstelle:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Wenn Sie versuchen, eine IPv4-Adresse für eine drahtlose Schnittstelle abzurufen, auf Ihrem Computer jedoch keine drahtlose Karte installiert ist, wird nur eine leere Zeichenfolge zurückgegeben. Gleiches gilt für die Ethernet-Schnittstelle.

Hoffe das hilft jemandem! :-)

BEARBEITEN:

Es wurde darauf hingewiesen (danke @NasBanov), dass diese Funktion zwar das Extrahieren der IP-Adresse auf viel bessere Weise als die Verwendung ermöglicht Dns.GetHostEntry(Dns.GetHostName()), jedoch nicht sehr gut mehrere Schnittstellen desselben Typs oder mehrere IP-Adressen auf einer einzigen Schnittstelle unterstützt . Es wird nur eine einzige IP-Adresse zurückgegeben, wenn möglicherweise mehrere Adressen zugewiesen sind. Um ALLE diese zugewiesenen Adressen zurückzugeben, können Sie einfach die ursprüngliche Funktion manipulieren, um immer ein Array anstelle einer einzelnen Zeichenfolge zurückzugeben. Zum Beispiel:

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

Diese Funktion gibt nun ALLE zugewiesenen Adressen für einen bestimmten Schnittstellentyp zurück. Um nur eine einzelne Zeichenfolge zu erhalten, können Sie die .FirstOrDefault()Erweiterung verwenden, um das erste Element im Array zurückzugeben, oder, wenn es leer ist, eine leere Zeichenfolge zurückgeben.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
compman2408
quelle
5
Dies ist eine bessere Lösung, da es an vielen Stellen keine DNS-Verwendbarkeit gibt und Schnittstellen mehrere IP-Adressen haben können. Ich benutze auch eine ähnliche Methode.
Mert Gülsoy
Das Problem dabei ist, dass Sie nur 1 IP-Adresse pro Schnittstelle zurückgeben ... die letzte IP für jeden.
Nas Banov
@ compman2408 - nicht wahr, eine einzelne Schnittstelle kann mehrere IPs haben. Alle Combos finden Sie unter en.wikipedia.org/wiki/Multihoming#Variants . Ein offensichtliches Beispiel ist, wenn sowohl IPv4 als auch IPv6 ausgeführt werden, aber in der Vergangenheit war ein einzelner Ethernet-Adapter an mehreren IPv4-Netzwerken beteiligt. Vielleicht ungewöhnlich - und doch vollkommen legal. ZB für Windows siehe windowsnetworking.com/articles-tutorials/windows-2003/…
Nas Banov
@NasBanov Diese Funktion ist nur zum Abrufen von IPv4-Adressen eingerichtet, daher werde ich nicht einmal über IPv6 und seine derzeitige Nutzlosigkeit sprechen. Ich bin mir bewusst, dass Multihoming eine Verbindung zu mehreren Netzwerken über mehrere Schnittstellen herstellt, habe jedoch noch nie davon gehört, eine Verbindung zu mehreren Netzwerken über dieselbe Schnittstelle herzustellen. Auch wenn Sie zu Recht den Eindruck haben, dass dies tatsächlich möglich ist, müssten <1% der Benutzer, die ihre Netzwerkkarte auf diese Weise verwenden, lediglich die Funktion ändern, um stattdessen ein Array zurückzugeben.
compman2408
1
Danke dafür. Zu Ihrer Information, zumindest unter .NET 3.5 Mono unter OSX wird item.OperationalStatusimmer zurückgegeben Unknown.
Gman
36

Hier ist eine modifizierte Version (von der von compman2408), die für mich funktioniert hat:

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

Sie können diese Methode beispielsweise wie folgt aufrufen:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Die Änderung: Ich rufe die IP von einem Adapter ab, dem eine Gateway-IP zugewiesen ist. Zweite Änderung: Ich habe docstrings und break-Anweisungen hinzugefügt, um diese Methode effizienter zu gestalten.

Gerardo H.
quelle
2
Clevere Lösung. Ich benutze das jetzt.
RQDQ
4
Hat das gleiche Problem wie der Code, von dem es abgeleitet wurde: Es gibt nur eine der IPs zurück, eine zufällige IP von vielen - die nicht die sein muss, die Sie benötigen. Es verdient die ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award
Nas Banov
1
@NasBanov, Sicher habe ich es verdient, wie ich in meinem Beitrag sage: "Was für mich funktioniert hat". :-)
Gerardo H
Dies ist der richtige Weg, danke dafür. Wenn Sie Loop-Back-Schalter für Emulatoren installiert haben, schlagen alle anderen Varianten fehl, während dieser erfolgreich ist!
DiamondDrake
1
Warum geben Sie nur die letzte gefundene IP-Adresse zurück, nicht die erste? Ein Simpel breakim Innersten ifoder ein returnwürde den Trick tun.
Martin Mulder
20

Dies ist der beste Code, den ich gefunden habe, um die aktuelle IP-Adresse abzurufen, um zu vermeiden, dass ein VMWare-Host oder eine andere ungültige IP-Adresse abgerufen wird.

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
quelle
Sie sollten wahrscheinlich erklären, warum dieser Code die Lösung für die Antwort ist. Können Sie tatsächlich eine Antwort auf die Frage erhalten, wenn Sie mit dem Internet verbunden sind und dies zu einem Fehler führt?
Philipp M
Die andere Methode verwendet nicht die IsDnsEligible- und PrefixOrigin-Validierung.
rodcesar.santos
@PhilippM Wenn die Adresse nicht DNS-berechtigt ist, handelt es sich um eine reservierte interne IP. Es ist nicht der Host des Internetproviders. Und wenn PrefixOrigin von einem DHCP-Server bereitgestellt wurde, ist dies möglicherweise die beste Adresswahl. Dies ist die einzigartige Funktion, die für mich funktioniert!
rodcesar.santos
1
@ user1551843 - das war toll, danke. Ich habe die alte veraltete GetHostByName-Methode verwendet, aber sie hat die IP eines VMWare-Adapters zurückgegeben :)
Jason Newland
Dies war die einzige Lösung, die für mich auf VPN + Wireless funktioniert hat. Danke dir.
Jay-Gefahr
12

Ich denke, die Verwendung von LinQ ist einfacher:

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()
Kapé
quelle
14
Das ist nicht LINQ, das sind Erweiterungsmethoden und Lambdas. Es besteht ein Unterschied.
Mark
10
@Mark - Wenn Sie nicht "using System.Linq;" hinzufügen Sie können die "Erste" Erweiterungsmethode jedoch nicht verwenden
BornToCode
5
Dies liegt daran, dass sich die Erweiterungsmethode in der Enumerable-Klasse befindet, die sich im System.Linq-Namespace befindet. Es ist immer noch nicht LINQ.
Mark
20
Markieren Sie, selbst in dieser Kurzform, dass die Anweisung tatsächlich LINQ-to-Objects verwendet, die mit Methodensyntax (Lambda) dargestellt werden. Die Abfragesyntax ist einfach syntaktischer Zucker, der zu einer Kette von IEnumerable-Erweiterungsmethodenaufrufen kompiliert wird. Dies ist LINQ-to-Objects. Quellen: Autor eines LINQ-to-SQL-Anbieters und einer Reihe von Artikeln zu diesem Thema.
Konstante g
9

Zum Lachen dachte ich, ich würde versuchen, eine einzelne LINQ-Anweisung zu erhalten, indem ich den neuen nullbedingten C # 6-Operator verwende. Sieht ziemlich verrückt und wahrscheinlich schrecklich ineffizient aus, aber es funktioniert.

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

Logik mit freundlicher Genehmigung von Gerardo H(und durch Bezugnahme compman2408).

Stajs
quelle
Auf jeden Fall lustig (+1), muss aber eigentlich gar nicht ineffizient sein. Erinnert mich an das Programmieren in LISP oder Forth :-)
Roland
6

Andere Möglichkeit, IP mithilfe des linq-Ausdrucks abzurufen:

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
quelle
5

@mrcheif Ich habe diese Antwort heute gefunden und sie war sehr nützlich, obwohl sie eine falsche IP-Adresse zurückgegeben hat (nicht, weil der Code nicht funktioniert), aber sie hat die falsche IP-Adresse für das Netzwerk angegeben, wenn Himachi ausgeführt wird.

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
quelle
2
Meinst du Logmein Hamachi? Es ist eine VPN-Lösung und bastelt am Netzwerkstapel. Da es sich um ein VPN handelt, erscheint es auch vernünftig, dass es die VPN-zugewiesene IP zurückgibt, wenn eine Verbindung besteht (nur meine Vermutung).
Mrchief
2
Völlig unzuverlässig. Es ist 192.0.0.0/8nicht nur kein korrekter Test für eine private IP-Adresse (es gibt 3 Bereiche, die sich alle von diesem unterscheiden), es kann auch ein Unternehmensnetzwerkbereich sein, also nicht so sehr "lokal".
ivan_pozdeev
5

Getestet mit einer oder mehreren LAN-Karten und virtuellen Maschinen

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
quelle
Beachten Sie, dass dieser nur für Ethernet funktioniert. Entfernen Sie die NetworkInterfaceType-Einschränkung, um Wi-Fi zu unterstützen.
Scor4er
3

Nur eine aktualisierte Version von mir mit 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
quelle
2

Voraussetzungen: Sie müssen die System.Data.Linq-Referenz hinzufügen und darauf verweisen

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

Ich hatte auch Probleme, die richtige IP zu erhalten.

Ich habe hier verschiedene Lösungen ausprobiert, aber keine hat mir den gewünschten Effekt gebracht. Bei fast allen bereitgestellten bedingten Tests wurde keine Adresse verwendet.

Das hat bei mir funktioniert, hoffe es hilft ...

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
quelle
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
quelle
str ist immer leer
aj.toulan
1

Beachten Sie, dass im Allgemeinen mehrere NAT-Übersetzungen und mehrere DNS-Server ausgeführt werden können, die jeweils auf unterschiedlichen NAT-Übersetzungsebenen ausgeführt werden.

Was ist, wenn Sie über NAT mit Carrier-Qualität verfügen und mit anderen Kunden desselben Carriers kommunizieren möchten? Im Allgemeinen wissen Sie es nie genau, da Sie bei jeder NAT-Übersetzung möglicherweise mit unterschiedlichen Hostnamen angezeigt werden.

sgjsfth sthseth
quelle
1

Veraltet weg, das funktioniert bei mir

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

Wenn wir die Antwort von Mrchief mit Linq aktualisieren, haben wir:

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

Dies gibt Adressen von allen Schnittstellen zurück, die Gateway-Adressen und Unicast-Adressen in zwei separaten Listen haben, IPV4 und 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
quelle
Ordentliche Lösung :)
Johan Franzén
1

Es gibt bereits viele Antworten, aber ich trage immer noch meine bei:

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

Einzeiler:

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

Hinweis: Suchen Sie nach dem letzten, da es nach einigen dem Gerät hinzugefügten Schnittstellen wie MobileHotspot, VPN oder anderen ausgefallenen virtuellen Adaptern immer noch funktioniert hat.

Nyconing
quelle
1
Wenn meine lokale IP 10.0.2.3 ist, wird sie nicht gefunden? Das ist wirklich komisch in diesem Code.
Frankhommers
@frankhommers wurde gesagt, überprüfen Sie nur für 16-Bit-Block
Nyconing
16-Bit-Blöcke können auch etwas anderes als 192.168 sein
frankhommers
0

Außerdem nur einfacher Code zum Abrufen der Client-IP:

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

Hoffe es hilft dir.

Majedur Rahaman
quelle
0
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].MapToIPv4() //returns 192.168.14.1

Geben Sie hier die Bildbeschreibung ein

Eran Peled
quelle
5
Ihre Antwort sollte eine Beschreibung der Funktionsweise für den Fall OP und auch für zukünftige Leser enthalten.
Ronak Dhoot
Es ist besser, eine Erklärung Ihrer Antwort für zukünftige Leser beizufügen.
Nicolas Gervais
0

Der Code von compman2408 wurde geändert, um ihn jeweils durchlaufen zu können 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;
}

Und man kann es so nennen:

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

Unter der gleichen Aktion

Funktion LocalIP ()

Host als Zeichenfolge dimmen = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString

txtIP.Text = Host

Geben Sie True zurück

Funktion beenden

YongJae Kim
quelle
Das folgende Beispiel zeigt dieselbe Aktion. Funktion LocalIP () Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString txtIP.Text = Host gibt True End-Funktion zurück
YongJae Kim
-2
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1]

eine Codezeile: D.

Fuzzybear
quelle
7
In einigen Fällen kann eine OutOfRangeException ausgelöst werden.
Loudenvier
5
Woher weißt du auch, welches du willst? Was für Sie richtig ist, kann für jemand anderen falsch sein.
Mark
-3

Wenn Sie über virtuelle Maschinen oder zusätzliche Netzwerkkarten verfügen, enthält die Adressliste möglicherweise andere Werte. Mein Vorschlag ist, die Einträge der Adressliste zu überprüfen und entsprechend zu drucken. In meinem Fall war Eintrag 3 die IPv4-Adresse meines Computers

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

Vergiss nicht hinzuzufügen using System.Net;

Bibaswann Bandyopadhyay
quelle
1
Korrektur; ALLE von ihnen sind die IP-Adresse Ihres Computers. Welches Sie jedoch wollen, ist eine ganz andere Geschichte. Beachten Sie, dass sich die Reihenfolge ändern kann und Sie aufgrund der von Ihnen verwendeten Methode immer raten werden.
Mark
Das habe ich gesagt, Sie sollten die Einträge der Adressliste überprüfen, und ja, es wird geraten, aber nachdem Sie alle Einträge gesehen haben, ist das Erraten nicht sehr schwierig
Bibaswann Bandyopadhyay
Wie würden Sie wissen, was angemessen ist? Mit der Lösung von compman2048 würden Sie zumindest wissen, welche mit welcher Schnittstelle verbunden ist.
Mark
Diese Lösung funktionierte auf meinem Computer nicht, da ich 2 WLAN-Schnittstellen, 2 virtuelle Maschinen und 1 Emulator habe und daher viele IPs habe. Aber wenn Sie nach einer internen Adresse suchen, die vom Router bereitgestellt wird, beginnt sie mit 192 oder 172 oder 10, so habe ich es verstanden
Bibaswann Bandyopadhyay
Es sei denn, Ihr Router verteilt öffentliche IP-Adressen, was ungewöhnlich, aber möglich ist.
Mark