389 Stimmen

Lokale IP-Adresse abrufen

Im Internet gibt es mehrere Stellen, die zeigen, wie man eine IP-Adresse erhält. Und viele von ihnen sehen so aus wie dieses Beispiel:

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

Bei diesem Beispiel erhalte ich mehrere IP-Adressen, aber ich bin nur an derjenigen interessiert, die der Router dem Computer zuweist, auf dem das Programm läuft: die IP, die ich jemandem geben würde, wenn er z. B. auf einen freigegebenen Ordner auf meinem Computer zugreifen möchte.

Wenn ich nicht an ein Netzwerk angeschlossen bin und direkt über ein Modem ohne Router mit dem Internet verbunden bin, möchte ich eine Fehlermeldung erhalten. Wie kann ich sehen, wenn mein Computer mit einem Netzwerk mit C# verbunden ist und wenn es dann die LAN-IP-Adresse zu erhalten.

566voto

Mrchief Punkte 72978

Um die lokale IP-Adresse zu erhalten:

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

Um zu prüfen, ob Sie verbunden sind oder nicht:

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

344voto

Es gibt eine genauere Methode, wenn mehrere IP-Adressen auf dem lokalen Rechner verfügbar sind. Connect einen UDP-Socket und liest dessen 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();
}

Connect auf einem UDP-Socket hat folgende Wirkung: Es legt das Ziel für Send / Recv alle Pakete von anderen Adressen verwirft und - was wir verwenden - den Socket in den Zustand "verbunden" überführt und die entsprechenden Felder einstellt. Dazu gehört auch die Überprüfung der Existenz der Route zum Ziel gemäß der Routing-Tabelle des Systems und die entsprechende Einstellung des lokalen Endpunkts. Der letzte Teil scheint offiziell undokumentiert zu sein, aber es sieht so aus, als ob er eine integrale Eigenschaft von Berkeley-Buchsen-API (ein Nebeneffekt des UDP-"Verbindungs"-Status), der sowohl unter Windows und Linux über Versionen und Distributionen hinweg.

Diese Methode gibt also die lokale Adresse an, die für die Verbindung mit dem angegebenen entfernten Host verwendet werden würde. Es wird keine echte Verbindung hergestellt, daher kann die angegebene entfernte IP unerreichbar sein.

152voto

compman2408 Punkte 2294

Ich weiß, dass ich damit vielleicht ein totes Pferd anremple, aber vielleicht kann ich damit jemandem helfen. Ich habe überall nach einer Möglichkeit gesucht, meine lokale IP-Adresse zu finden, aber überall, wo ich sie finde, steht, dass ich sie verwenden soll:

Dns.GetHostEntry(Dns.GetHostName());

Das gefällt mir überhaupt nicht, weil damit einfach alle Adressen, die Ihrem Computer zugewiesen sind, abgerufen werden. Wenn Sie mehrere Netzwerkschnittstellen haben (was heutzutage bei so gut wie allen Computern der Fall ist), haben Sie keine Ahnung, welche Adresse zu welcher Netzwerkschnittstelle gehört. Nachdem ich einige Nachforschungen angestellt habe, habe ich eine Funktion erstellt, die die NetworkInterface-Klasse verwendet und die Informationen aus ihr herausholt. 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;
}

Um die IPv4-Adresse Ihrer Ethernet-Netzwerkschnittstelle zu erhalten, rufen Sie jetzt auf:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Oder Ihre Wireless-Schnittstelle:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Wenn Sie versuchen, eine IPv4-Adresse für eine drahtlose Schnittstelle zu erhalten, Ihr Computer aber keine drahtlose Karte installiert hat, wird nur eine leere Zeichenfolge zurückgegeben. Dasselbe gilt für die Ethernet-Schnittstelle.

Hoffentlich hilft das jemandem! :-)

EDITです。

Es wurde darauf hingewiesen (danke @NasBanov), dass diese Funktion zwar die IP-Adresse viel besser extrahiert als die Funktion Dns.GetHostEntry(Dns.GetHostName()) Es unterstützt nicht sehr gut mehrere Schnittstellen desselben Typs oder mehrere IP-Adressen auf einer einzigen Schnittstelle. Es gibt nur eine einzige IP-Adresse zurück, wenn möglicherweise mehrere Adressen zugewiesen sind. Um ALLE diese zugewiesenen Adressen zurückzugeben, könnten Sie die ursprüngliche Funktion einfach so manipulieren, dass sie immer ein Array anstelle eines einzelnen Strings zurückgibt. 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 einzige Zeichenkette zu erhalten, können Sie die Funktion .FirstOrDefault() Erweiterung, um das erste Element im Array zurückzugeben oder, falls es leer ist, eine leere Zeichenkette zurückzugeben.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();

121voto

Pure.Krome Punkte 81543

Refactoring von Mrcheifs Code zur Nutzung von Linq (d.h. .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);
}

:)

47voto

Gerardo H Punkte 674

Hier ist eine modifizierte Version (von compman2408), die bei mir 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 zum Beispiel wie folgt aufrufen:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X