web-dev-qa-db-fra.com

Obtenir une adresse IP publique / externe?

Je n'arrive pas à obtenir ou à trouver des informations sur la recherche de l'adresse IP publique de mes routeurs? Est-ce parce que cela ne peut pas être fait de cette façon et qu'il faudrait l'obtenir à partir d'un site Web?

50
arbme

En utilisant C #, avec webclient, c’est court.

public static void Main(string[] args)
{
    string externalip = new WebClient().DownloadString("http://icanhazip.com");            
    Console.WriteLine(externalip);
}

Ligne de commande (fonctionne sous Linux et Windows)

wget -qO- http://bot.whatismyipaddress.com

OR

curl http://ipinfo.io/ip
84
user_v
static void Main(string[] args)
{
    HTTPGet req = new HTTPGet();
    req.Request("http://checkip.dyndns.org");
    string[] a = req.ResponseBody.Split(':');
    string a2 = a[1].Substring(1);
    string[] a3=a2.Split('<');
    string a4 = a3[0];
    Console.WriteLine(a4);
    Console.ReadLine();
}

Faites cette petite astuce avec Check IP DNS

Utilisez HTTPGet classe i trouvée sur Goldb-Httpget C #

69
filippakoc

Avec .Net WebRequest:

  public static string GetPublicIP()
    {
        string url = "http://checkip.dyndns.org";
        System.Net.WebRequest req = System.Net.WebRequest.Create(url);
        System.Net.WebResponse resp = req.GetResponse();
        System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
        string response = sr.ReadToEnd().Trim();
        string[] a = response.Split(':');
        string a2 = a[1].Substring(1);
        string[] a3 = a2.Split('<');
        string a4 = a3[0];
        return a4;
    }
36
r.zarei
string pubIp =  new System.Net.WebClient().DownloadString("https://api.ipify.org");
29
suneel ranga

Utiliser un excellent service similaire

private string GetPublicIpAddress()
{
    var request = (HttpWebRequest)WebRequest.Create("http://ifconfig.me");

    request.UserAgent = "curl"; // this will tell the server to return the information as if the request was made by the linux "curl" command

    string publicIPAddress;

    request.Method = "GET";
    using (WebResponse response = request.GetResponse())
    {
        using (var reader = new StreamReader(response.GetResponseStream()))
        {
            publicIPAddress = reader.ReadToEnd();
        }
    }

    return publicIPAddress.Replace("\n", "");
}
20
Riccardo Bassilichi

En théorie, votre routeur devrait pouvoir vous indiquer l'adresse IP publique du réseau, mais la façon de le faire sera nécessairement incohérente/non simple, si possible avec certains périphériques de routeur.

La méthode la plus simple et la plus fiable consiste à envoyer une requête à une page Web qui renvoie votre adresse IP telle que la voit le serveur Web. Dyndns.org fournit un bon service pour cela:

http://checkip.dyndns.org/

Ce qui est retourné est un document HTML extrêmement simple/court, contenant le texte Current IP Address: 157.221.82.39 _ (faux IP), qui est simple à extraire de la réponse HTTP.

13
Noldorin

Développer ceci réponse par @ suneel ranga :

static System.Net.IPAddress GetPublicIp(string serviceUrl = "https://ipinfo.io/ip")
{
    return System.Net.IPAddress.Parse(new System.Net.WebClient().DownloadString(serviceUrl));
}

Où vous utiliseriez un service avec System.Net.WebClient qui affiche simplement l’adresse IP sous forme de chaîne et utilise le System.Net.IPAddress objet. Voici quelques services de ce type *:

* Certains services ont été mentionnés dans cette question et parmi ceux-ci réponses du site superutilisateur .

10
ShooShoSha

J'ai trouvé que http://checkip.dyndns.org/ me donnait des balises html que je devais traiter, mais https://icanhazip.com/ me donnait simplement une chaîne simple. Malheureusement, https://icanhazip.com/ me donne l'adresse IP6 et j'avais besoin d'ip4. Heureusement, vous avez le choix entre 2 sous-domaines, ipv4.icanhazip.com et ipv6.icanhazip.com.

        string externalip = new WebClient().DownloadString("https://ipv4.icanhazip.com/");
        Console.WriteLine(externalip);
        Console.WriteLine(externalip.TrimEnd());
7
Dowlers

Avec quelques lignes de code, vous pouvez écrire votre propre serveur HTTP pour cela.

HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://+/PublicIP/");
listener.Start();
while (true)
{
    HttpListenerContext context = listener.GetContext();
    string clientIP = context.Request.RemoteEndPoint.Address.ToString();
    using (Stream response = context.Response.OutputStream)
    using (StreamWriter writer = new StreamWriter(response))
        writer.Write(clientIP);

    context.Response.Close();
}

Ensuite, chaque fois que vous avez besoin de connaître votre adresse IP publique, vous pouvez le faire.

WebClient client = new WebClient();
string ip = client.DownloadString("http://serverIp/PublicIP");
6
Despertar

Moyen rapide d'obtenir une adresse IP externe sans aucune connexion. Aucune connexion HTTP n'est nécessaire pour cela.

vous devez d’abord ajouter NATUPNPLib.dll dans Referance, puis le sélectionner dans les références et vérifier à partir de la fenêtre de propriétés Embed Interop Type to False

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NATUPNPLib; // Add this dll from referance and chande Embed Interop Interop to false from properties panel on visual studio
using System.Net;

namespace Client
{
    class NATTRAVERSAL
    {
        //This is code for get external ip
        private void NAT_TRAVERSAL_ACT()
        {
            UPnPNATClass uPnP = new UPnPNATClass();
            IStaticPortMappingCollection map = uPnP.StaticPortMappingCollection;

            foreach (IStaticPortMapping item in map)
            {
                    Debug.Print(item.ExternalIPAddress); //This line will give you external ip as string
                    break;
            }
        }
    }
}
6
Toprak

checkip.dyndns.org ne fonctionne pas toujours correctement. Par exemple, pour ma machine, il affiche l'adresse interne après NAT:

Current IP Address: 192.168.1.120

Je pense que c'est ce qui se passe, car j'ai ma zone DNS locale derrière NAT et mon navigateur envoie pour vérifier son adresse IP locale, qui est renvoyée.

En outre, http est un protocole basé sur TCP, lourd et orienté texte, donc peu approprié pour une demande régulière rapide et efficace pour une adresse IP externe. Je suggère d'utiliser STUN binaire basé sur UDP, spécialement conçu à cet effet:

http://en.wikipedia.org/wiki/STUN

Le serveur STUN est comme "miroir UDP". Vous regardez, et voyez "à quoi je ressemble".

Il existe de nombreux serveurs STUN publics dans le monde entier, sur lesquels vous pouvez demander votre adresse IP externe. Par exemple, voir ici:

http://www.voip-info.org/wiki/view/STUN

Vous pouvez télécharger n'importe quelle bibliothèque client STUN, d'Internet, par exemple, ici:

http://www.codeproject.com/Articles/18492/STUN-Client

Et l'utiliser.

5
olegarch

Je le fais en utilisant HttpClient de System.Net.Http:

public static string PublicIPAddress()
{
    string uri = "http://checkip.dyndns.org/";
    string ip = String.Empty;

    using (var client = new HttpClient())
    {
        var result = client.GetAsync(uri).Result.Content.ReadAsStringAsync().Result;

        ip = result.Split(':')[1].Split('<')[0];
    }

    return ip;
}
4
Davor Zubak

En gros, je préfère utiliser des sauvegardes supplémentaires au cas où l'une des adresses IP n'est pas accessible. Donc j'utilise cette méthode.

 public static string GetExternalIPAddress()
        {
            string result = string.Empty;
            try
            {
                using (var client = new WebClient())
                {
                    client.Headers["User-Agent"] =
                    "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) " +
                    "(compatible; MSIE 6.0; Windows NT 5.1; " +
                    ".NET CLR 1.1.4322; .NET CLR 2.0.50727)";

                    try
                    {
                        byte[] arr = client.DownloadData("http://checkip.amazonaws.com/");

                        string response = System.Text.Encoding.UTF8.GetString(arr);

                        result = response.Trim();
                    }
                    catch (WebException)
                    {                       
                    }
                }
            }
            catch
            {
            }

            if (string.IsNullOrEmpty(result))
            {
                try
                {
                    result = new WebClient().DownloadString("https://ipinfo.io/ip").Replace("\n", "");
                }
                catch
                {
                }
            }

            if (string.IsNullOrEmpty(result))
            {
                try
                {
                    result = new WebClient().DownloadString("https://api.ipify.org").Replace("\n", "");
                }
                catch
                {
                }
            }

            if (string.IsNullOrEmpty(result))
            {
                try
                {
                    result = new WebClient().DownloadString("https://icanhazip.com").Replace("\n", "");
                }
                catch
                {
                }
            }

            if (string.IsNullOrEmpty(result))
            {
                try
                {
                    result = new WebClient().DownloadString("https://wtfismyip.com/text").Replace("\n", "");
                }
                catch
                {
                }
            }

            if (string.IsNullOrEmpty(result))
            {
                try
                {
                    result = new WebClient().DownloadString("http://bot.whatismyipaddress.com/").Replace("\n", "");
                }
                catch
                {
                }
            }

            if (string.IsNullOrEmpty(result))
            {
                try
                {
                    string url = "http://checkip.dyndns.org";
                    System.Net.WebRequest req = System.Net.WebRequest.Create(url);
                    System.Net.WebResponse resp = req.GetResponse();
                    System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
                    string response = sr.ReadToEnd().Trim();
                    string[] a = response.Split(':');
                    string a2 = a[1].Substring(1);
                    string[] a3 = a2.Split('<');
                    result = a3[0];
                }
                catch (Exception)
                {
                }
            }

            return result;
        }

Afin de mettre à jour le contrôle de l’interface graphique (WPF, .NET 4.5), par exemple certains Label j’utilise ce code

 void GetPublicIPAddress()
 {
            Task.Factory.StartNew(() =>
            {
                var ipAddress = SystemHelper.GetExternalIPAddress();

                Action bindData = () =>
                {
                    if (!string.IsNullOrEmpty(ipAddress))
                        labelMainContent.Content = "IP External: " + ipAddress;
                    else
                        labelMainContent.Content = "IP External: ";

                    labelMainContent.Visibility = Visibility.Visible; 
                };
                this.Dispatcher.InvokeAsync(bindData);
            });

 }

J'espère que c'est utile.

Here est un exemple d'application qui inclura ce code.

4
Developer
public static string GetPublicIP()
{
    return new System.Net.WebClient().DownloadString("https://ipinfo.io/ip").Replace("\n","");
}
4
Kamil Smrčka

Lorsque je débogue, j'utilise l'option suivante pour construire l'URL pouvant être appelée de manière externe, mais vous pouvez simplement utiliser les deux premières lignes pour obtenir votre adresse IP publique:

public static string ExternalAction(this UrlHelper helper, string actionName, string controllerName = null, RouteValueDictionary routeValues = null, string protocol = null)
{
#if DEBUG
    var client = new HttpClient();
    var ipAddress = client.GetStringAsync("http://ipecho.net/plain").Result; 
    // above 2 lines should do it..
    var route = UrlHelper.GenerateUrl(null, actionName, controllerName, routeValues, helper.RouteCollection, helper.RequestContext, true); 
    if (route == null)
    {
        return route;
    }
    if (string.IsNullOrEmpty(protocol) && string.IsNullOrEmpty(ipAddress))
    {
        return route;
    }
    var url = HttpContext.Current.Request.Url;
    protocol = !string.IsNullOrWhiteSpace(protocol) ? protocol : Uri.UriSchemeHttp;
    return string.Concat(protocol, Uri.SchemeDelimiter, ipAddress, route);
#else
    helper.Action(action, null, null, HttpContext.Current.Request.Url.Scheme)
#endif
}
3
Ostati

J'ai refactored la réponse de l'Académie de Programmeur à un code plus court et je l'ai modifié pour qu'il ne touche que https:// URL:

    public static string GetExternalIPAddress()
    {
        string result = string.Empty;

        string[] checkIPUrl =
        {
            "https://ipinfo.io/ip",
            "https://checkip.amazonaws.com/",
            "https://api.ipify.org",
            "https://icanhazip.com",
            "https://wtfismyip.com/text"
        };

        using (var client = new WebClient())
        {
            client.Headers["User-Agent"] = "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) " +
                "(compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)";

            foreach (var url in checkIPUrl)
            {
                try
                {
                    result = client.DownloadString(url);
                }
                catch
                {
                }

                if (!string.IsNullOrEmpty(result))
                    break;
            }
        }

        return result.Replace("\n", "").Trim();
    }
}
3
Mitch Wheat

Les réponses basées sur l'utilisation de services Web externes ne sont pas tout à fait correctes, car elles ne répondent pas réellement à la question posée:

... informations sur la recherche de mes routeurs IP publics


Explication

Tous les services en ligne renvoient l'adresse IP externe , mais cela ne signifie pas essentiellement que cette adresse est attribuée au routeur de l'utilisateur.

Le routeur peut se voir attribuer une autre adresse IP locale des réseaux d’infrastructure ISP. Concrètement, cela signifie que ce routeur ne peut héberger aucun service disponible sur Internet. Cela peut être bon pour la sécurité de la plupart des utilisateurs à domicile, mais pas pour les geeks qui hébergent des serveurs chez eux.

Voici comment vérifier si le routeur a une adresse IP externe:

trace route to web server behind ISP

Selon l'article Wikipedia , les plages d'adresses IP 10.0.0.0 – 10.255.255.255, 172.16.0.0 – 172.31.255.255 et 192.168.0.0 – 192.168.255.255 sont utilisés pour les réseaux privés, c’est-à-dire locaux.

Découvrez ce qui se passe lorsque vous tracez un itinéraire vers un hôte distant auquel un routeur est attribué avec une adresse IP externe:

trace route to web server with external IP address

Je t'ai eu! Le premier saut commence à partir de 31.* à présent. Cela signifie clairement qu'il n'y a rien entre votre routeur et Internet.


Solution

  1. Faites Ping à une adresse avec Ttl = 2
  2. Évaluez d'où vient la réponse.

TTL = 2 ne doit pas être suffisant pour atteindre l'hôte distant. Hop # 1 Host émettra "Reply from <ip address>: TTL expired in transit." révélant son adresse IP.

La mise en oeuvre

try
{
    using (var ping = new Ping())
    {
        var pingResult = ping.Send("google.com");
        if (pingResult?.Status == IPStatus.Success)
        {
            pingResult = ping.Send(pingResult.Address, 3000, "ping".ToAsciiBytes(), new PingOptions { Ttl = 2 });

            var isRealIp = !Helpers.IsLocalIp(pingResult?.Address);

            Console.WriteLine(pingResult?.Address == null
                ? $"Has {(isRealIp ? string.Empty : "no ")}real IP, status: {pingResult?.Status}"
                : $"Has {(isRealIp ? string.Empty : "no ")}real IP, response from: {pingResult.Address}, status: {pingResult.Status}");

            Console.WriteLine($"ISP assigned REAL EXTERNAL IP to your router, response from: {pingResult?.Address}, status: {pingResult?.Status}");
        }
        else
        {
            Console.WriteLine($"Your router appears to be behind ISP networks, response from: {pingResult?.Address}, status: {pingResult?.Status}");
        }
    }
}
catch (Exception exc)
{
    Console.WriteLine("Failed to resolve external ip address by ping");
}

Small helper est utilisé pour vérifier si une adresse IP appartient à un réseau privé ou public:

public static bool IsLocalIp(IPAddress ip) {
    var ipParts = ip.ToString().Split(new [] { "." }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();

    return (ipParts[0] == 192 && ipParts[1] == 168) 
        || (ipParts[0] == 172 && ipParts[1] >= 16 && ipParts[1] <= 31) 
        ||  ipParts[0] == 10;
}
3
Alex Khoroshylov

La plupart des réponses ont mentionné http://checkip.dyndns.org en solution. Pour nous, ça n'a pas bien marché. Nous avons fait face à Timemouts beaucoup de temps. C'est vraiment inquiétant si votre programme est dépendant de la détection IP.

En tant que solution, nous utilisons la méthode suivante dans l’une de nos applications de bureau:

    // Returns external/public ip
    protected string GetExternalIP()
    {
        try
        {
            using (MyWebClient client = new MyWebClient())
            {
                client.Headers["User-Agent"] =
                "Mozilla/4.0 (Compatible; Windows NT 5.1; MSIE 6.0) " +
                "(compatible; MSIE 6.0; Windows NT 5.1; " +
                ".NET CLR 1.1.4322; .NET CLR 2.0.50727)";

                try
                {
                    byte[] arr = client.DownloadData("http://checkip.amazonaws.com/");

                    string response = System.Text.Encoding.UTF8.GetString(arr);

                    return response.Trim();
                }
                catch (WebException ex)
                {
                    // Reproduce timeout: http://checkip.amazonaws.com:81/

                    // trying with another site
                    try
                    {
                        byte[] arr = client.DownloadData("http://icanhazip.com/");

                        string response = System.Text.Encoding.UTF8.GetString(arr);

                        return response.Trim();
                    }
                    catch (WebException exc)
                    { return "Undefined"; }
                }
            }
        }
        catch (Exception ex)
        {
            // TODO: Log trace
            return "Undefined";
        }
    }

Le bon côté est que les deux sites renvoient l'IP en format clair. Donc, les opérations sur les chaînes sont évitées.

Pour vérifier votre logique dans la clause catch, vous pouvez reproduire Timeout en frappant un port non disponible. par exemple: http://checkip.amazonaws.com:81/

2
ThePCWizard

L'API IPIFY est agréable, car il peut répondre en texte brut et en JSON. Il peut également faire des rappels, etc. Le seul problème est qu’il répond en IPv4, pas 6.

2
carefulnow1

Meilleure réponse que j'ai trouvée

Pour obtenir l'adresse IP à distance le plus rapidement possible. Vous devez utiliser un téléchargeur ou créer un serveur sur votre ordinateur.

L’inconvénient de l’utilisation de ce code simple (recommandé) est qu’il vous faudra 3 à 5 secondes pour obtenir votre adresse IP distante, car le WebClient, une fois initialisé, prend toujours 3 à 5 secondes pour vérifier vos paramètres de proxy.

 public static string GetIP()
 {
            string externalIP = "";
            externalIP = new WebClient().DownloadString("http://checkip.dyndns.org/");
            externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                                           .Matches(externalIP)[0].ToString();
            return externalIP;
 }

Voici comment je l'ai corrigé. (La première fois prend encore 3-5 secondes), mais après cela, votre adresse IP distante sera toujours obtenue en 0-2 secondes, selon votre connexion.

public static WebClient webclient = new WebClient();
public static string GetIP()
{
    string externalIP = "";
    externalIP = webclient.DownloadString("http://checkip.dyndns.org/");
    externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"))
                                   .Matches(externalIP)[0].ToString();
    return externalIP;
}
2
SSpoke
public string GetClientIp() {
    var ipAddress = string.Empty;
    if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) {
        ipAddress = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
    } else if (System.Web.HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"] != null &&
               System.Web.HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"].Length != 0) {
        ipAddress = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_CLIENT_IP"];
    } else if (System.Web.HttpContext.Current.Request.UserHostAddress.Length != 0) {
        ipAddress = System.Web.HttpContext.Current.Request.UserHostName;
    }
    return ipAddress;
} 

fonctionne parfaitement

1
kayabaku
using System.Net;

private string GetWorldIP()
{
    String url = "http://bot.whatismyipaddress.com/";
    String result = null;

    try
    {
        WebClient client = new WebClient();
        result = client.DownloadString(url);
        return result;
    }
    catch (Exception ex) { return "127.0.0.1"; }
}

Boucle utilisée comme solution de secours pour que rien ne se casse fatalement.

1
Speedz

Vous pouvez utiliser Telnet pour interroger votre routeur par programme pour connaître l'adresse IP WAN.

La partie Telnet

La partie Telnet peut être réalisée à l'aide, par exemple, de ce code Telnet minimaliste en tant qu'API pour envoyer une commande Telnet à votre routeur et obtenir la réponse de celui-ci. Le reste de cette réponse suppose que vous êtes configuré d'une manière ou d'une autre pour envoyer une commande Telnet et récupérer la réponse dans votre code.

Limites d'approche

Je dirai d'emblée que l'un des inconvénients de l'interrogation du routeur par rapport à d'autres approches est que le code que vous écrivez est susceptible d'être assez spécifique au modèle de votre routeur. Cela dit, il peut s’avérer une approche utile qui ne repose pas sur des serveurs externes et vous pouvez de toute façon souhaiter accéder à votre routeur à partir de votre propre logiciel à d’autres fins, telles que la configuration et le contrôle, ce qui rend plus intéressant l’écriture de code spécifique.

Exemple de commande et de réponse du routeur

L'exemple ci-dessous ne conviendra pas pour tous les routeurs, mais illustre l'approche en principe. Vous devrez modifier les détails en fonction des commandes et des réponses de votre routeur.

Par exemple, la manière d'obtenir que votre routeur affiche le WAN IP peut être la commande Telnet suivante:

connection list

La sortie peut consister en une liste de lignes de texte, une par connexion, avec l'adresse IP en décalage 39. La ligne pour la connexion WAN peut être identifiable à partir du mot "Internet" quelque part dans la ligne:

  RESP: 3947  17.110.226. 13:443       146.200.253. 16:60642     [R..A] Internet      6 tcp   128
<------------------  39  -------------><--  WAN IP -->

La sortie peut associer à chaque segment d’adresse IP trois caractères avec des espaces que vous devrez supprimer. (Dans l'exemple ci-dessus, vous devez convertir "146.200.253. 16" en "146.200.253.16".)

En expérimentant ou en consultant la documentation de référence de votre routeur, vous pouvez définir la commande à utiliser pour votre routeur spécifique et savoir comment interpréter la réponse du routeur.

Code pour obtenir le WAN IP

(Supposons que vous avez une méthode sendRouterCommand pour la partie Telnet — voir ci-dessus.)

À l'aide de l'exemple de routeur décrit ci-dessus, le code suivant obtient l'adresse IP WAN:

private bool getWanIp(ref string wanIP)
{
    string routerResponse = sendRouterCommand("connection list");

    return (getWanIpFromRouterResponse(routerResponse, out wanIP));
}

private bool getWanIpFromRouterResponse(string routerResponse, out string ipResult)
{
    ipResult = null;
    string[] responseLines = routerResponse.Split(new char[] { '\n' });

    //  RESP: 3947  17.110.226. 13:443       146.200.253. 16:60642     [R..A] Internet      6 tcp   128
    //<------------------  39  -------------><---  15   --->

    const int offset = 39, length = 15;

    foreach (string line in responseLines)
    {
        if (line.Length > (offset + length) && line.Contains("Internet"))
        {
            ipResult = line.Substring(39, 15).Replace(" ", "");
            return true;
        }
    }

    return false;
}
1
Reg Edit