Feedback

C# - Eigene, externe IP-Adresse ermitteln

Veröffentlicht von am 2/25/2017
(0 Bewertungen)
Hallo an alle,
diese Methode gibt die eigene, öffentliche IP-Adresse zurück.

Usings:
using System.IO;
using System.Net;

Credits:
Koopakiller danke für die Tipps.
        /// <summary>
        /// Öffentliche IP auslesen
        /// </summary>
        /// <returns>IP-Adresse</returns>
        IPAddress GetMyIP()
        {
            string Ip, Url = "http://bot.whatismyipaddress.com/";

            HttpWebRequest Req = (HttpWebRequest)WebRequest.Create(Url);

            using (HttpWebResponse Res = (HttpWebResponse)Req.GetResponse())
            {
                using (StreamReader Str = new StreamReader(Res.GetResponseStream()))
                {
                    Ip = Str.ReadToEnd();
                }
            }

            return IPAddress.Parse(Ip);
        }
Abgelegt unter IP, IP-Adresse, ExterneIP, ÖffentlicheIP.

8 Kommentare zum Snippet

Koopakiller schrieb am 2/25/2017:
Im Grunde gilt das selbe, was ich hier schon mal kommentierte:
https://dotnet-snippets.de/snippet/die-oeffentliche-ip-vom-provider-abfragen/15159
Tobi82 schrieb am 2/27/2017:
Hallo Koopakiller,

Zu Regex:
Wie gesagt bin da kein Profi, wer einen besseren Pattern hat kann ihn gern posten :-)
Auf MyIp.is funktioniert das übrigens auch:
            Match m = Regex.Match(qtxt, "<a.*>(.*?)</a>");
return m.Groups[1].ToString();
... wird nur nicht helfen, wenn die Seite wirklich kein IPv6 kann !?

Zu Seiten die nur die IP anzeigen:
Da sollten meine "FTP-Methoden" greifen, da die Seite, die man sich selber auf den FTP hochladen kann (wie in meinem Beispiel) auch nur die IP anzeigt.

Zur IPAddress-Klasse:
Um sich die IP in der Anwendung (Label usw.) oder Console anzeigen zu lassen, brauch ich doch sowieso einen String warum dann umständlich über die IPAddress-Klasse ausgeben lassen?
Koopakiller schrieb am 2/27/2017:
Vielleicht bastle ich mal ein Pattern zusammen...

Nur FTP ist nicht HTTP. Ich dachte an Seiten wie http://bot.whatismyipaddress.com/ die nur die IP-Anzeigen (auch meine richtige IPv6) und über HTTP abgegriffen werden können. Wenn die Seite eine IPv4 anzeigt wird es trotzdem gehen, man müsste eben das Pattern anpassen. Einen Unterschied dürfte es trotzdem nicht machen, sofern man auch das Protokoll aufpasst.

Zur IPAddress-Klasse:
Weil das der gute Stil ist. Erstmal validiert die Klasse die IP und kann ggf. Fehler finden und die Verarbeitung direkt in der Fehlerhaften Methode abbrechen. Außerdem nimmt jede mir bekannte .NET Methode nur Objekte ebendieser Klasse an und nie Strings.
Auch bietet die IPAddress-Klasse ein paar hilfreiche Verarbeitungsfunktionen an.
Der Fall, dass ein Benutzer eine IP sehen muss ist sicher manchmal gegeben, aber auch dann willst du ihm sicher nichts falsches Anzeigen - oder?
Koopakiller schrieb am 2/27/2017:
PS: Dein Regex ist auch nicht sonderlich sicher, beispielsweise geht folgender String, der aber keine IP ist: "300.300.300.0"
Zu dem IPv6-Regex...Das Teil wird sicher weit über 100 Zeichen lang und alles andere als Verständlich. Da würde ich dann kein Regex mehr verwenden, sondern manuell auf die Suche gehen und das syntaktisch abgleichen.
Tobi82 schrieb am 2/28/2017:
Hey Koopakiller,
danke dir mal für deine Kommentare, ich habe mal eine Methode geschrieben die dir gefallen könnte:
        IPAddress getMyIP()
{
HttpWebRequest req = (HttpWebRequest)WebRequest.Create("http://bot.whatismyipaddress.com/");
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
StreamReader str = new StreamReader(res.GetResponseStream());

string ip = str.ReadToEnd();
str.Close();
res.Close();

return IPAddress.Parse(ip);
}
IPAddress Klasse und dein Link wird verwendet, das Ganze ohne Regex.

Ich muss zugeben so gefällts mir auch besser. Falls man die IP als String will, kann man ja einfach konvertieren.

Wenn du keinen Fehler mehr findest pack ich die Methode oben mit rein :)
Koopakiller schrieb am 3/1/2017:
So gefällt's mir :)
Ich habe es jetzt nicht nochmal getestet, aber von der Logik her passt es jetzt. Aber es geht meist noch eine Stufe besser.

1. Einmal schreibt man in C# öffentliche Member und Methoden groß.
2. Ich benutze lieber var anstelle der Typ-Namen, aber das ist Ansichtssache.
3. using-Blöcke sind sehr zu empfehlen. Damit werden Stream etc. auch im Fehlerfall geschlossen, was sonst nicht der Fall ist. Das ist syntatic sugar für einen try...finally-Block. Lies am besten mal in der MSDN nach ;)

Jetzt, wo ich das so schreibe, das gilt für alle deine Methoden.

Sofern man alle Methoden zusammen halten will, wäre es vielleicht sinnvoll den redundanten Code in eine Art "Basis-Methode" auszulagern. Aber das muss jeder für sich entscheiden, zumal mal ja eigentlich nur eine der Methoden braucht.
Tobi82 schrieb am 3/1/2017:
Hab das Snippet mal geändert und alles überflüssige weg gelassen ;)
Thx
timonator schrieb am 8/30/2017:
Es ist nicht unwahrscheinlich, daß der Service mal nicht zu ereichen ist, wäre doch unschön, wenn es dann jedes mal knallt.
Die Exeption würde ich einfach via 'Try Catch' schlucken und 'Nothing' ausgeben.
Außerdem gefällt mir die Benamung nicht, weil nicht eindeutig genug, z.B. der Methodenname "GetMyIP", könnte auch eine LAN IP meinen.
Daher habe ich nochmal drüber gebügelt, so wie ich es machen würde.:
/// <summary>
/// Get public IP adress, from "http://bot.whatismyipaddress.com/".
/// </summary>
/// <returns> IPAddress </returns>
private IPAddress GetPublicIP()
{
string ip;
WebRequest request = WebRequest.Create("http://bot.whatismyipaddress.com/");
try {
using (WebResponse response = request.GetResponse()) {
using (StreamReader reader = new StreamReader(response.GetResponseStream())) {
ip = reader.ReadToEnd();
}
}
} catch (Exception ex) {
return null;
}
return IPAddress.Parse(ip);
}
 

Logge dich ein, um hier zu kommentieren!