Comment obtenir l'adresse IP du serveur sur lequel mon application C # s'exécute?

365

J'exécute un serveur et je souhaite afficher ma propre adresse IP.

Quelle est la syntaxe pour obtenir la propre adresse IP de l'ordinateur (si possible, externe)?

Quelqu'un a écrit le code suivant.

IPHostEntry host;
string localIP = "?";
host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress ip in host.AddressList)
{
    if (ip.AddressFamily.ToString() == "InterNetwork")
    {
        localIP = ip.ToString();
    }
}
return localIP;

Cependant, je me méfie généralement de l'auteur et je ne comprends pas ce code. Y a-t-il une meilleure façon de le faire?

Nefzen
la source
1
En ce qui concerne l'adresse IP externe, je ne pense pas qu'il existe une approche locale pour récupérer cela. L'hôte local peut être derrière un routeur NAT qui traduit des adresses de réseau local en adresses publiques. Existe-t-il un moyen (local) de vérifier si c'est le cas? Je n'en connais aucun ...
Thiago Arrais
L'échantillon utilise le DNS pour obtenir l'adresse IP, j'ai eu de l'expérience avec DNS ayant des informations erronées. Dans ce cas, l'échantillon pourrait répondre avec des informations erronées .
leiflundgren
@leiflundgren J'ai également eu de l'expérience avec DNS ayant des informations erronées. Ma réponse décrit comment j'ai obtenu l'adresse IP dont j'avais besoin sans compter sur DNS lorsque j'ai fait face à cette situation.
Apprenti du Dr Wily, le
13
Utilisation de LINQ:Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(o => o.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).First().ToString()
Luis Perez
2
Il s'agit d'une situation typique où les utilisateurs ayant des besoins complètement différents ont tendance à poser la même question. Certaines personnes veulent savoir comment leur ordinateur peut être atteint à partir du réseau public. La réponse canonique est STUN , bien que beaucoup répondent avec des hacks dépendant de tiers aléatoires. Certaines personnes veulent simplement connaître leur adresse IP sur le ou les réseaux locaux. Les bonnes réponses dans ce cas mentionnent la méthode NetworkInterface.GetAllNetworkInterfaces .
Stéphane Gourichon

Réponses:

237

Non, c'est à peu près la meilleure façon de le faire. Comme une machine pourrait avoir plusieurs adresses IP, vous devez répéter leur collecte pour trouver la bonne.

Éditer: La seule chose que je voudrais changer serait de changer ceci:

if (ip.AddressFamily.ToString() == "InterNetwork")

pour ça:

if (ip.AddressFamily == AddressFamily.InterNetwork)

Il n'y a pas besoin d' ToStringune énumération pour comparaison.

Andrew Hare
la source
3
Je veux l'adresse IP externe, si possible. Je suppose que ce ne sera pas possible si je suis derrière NAT.
Nefzen
3
Non, votre machine ne connaîtra que son adresse NAT.
Andrew Hare,
1
Je suis à peu près sûr que vous devrez accéder à un serveur externe pour l'adresse externe.
Thiago Arrais
29
Je suggérerais également une breakdéclaration après que l'IP a été trouvée pour éviter d'itérer inutilement plus loin dans la collection (dans ce cas, je doute que l'impact sur les performances aura de l'importance, mais j'aime souligner généralement de bonnes habitudes de codage)
Eric
7
Notez que cela peut échouer lorsqu'une machine possède plusieurs ports 'InterNetwork' (dans mon cas: une carte Ethernet et un port de machine virtuelle). Le code actuel vous donnera la dernière IP de la liste.
Christian Studer
168

La seule façon de connaître votre adresse IP publique est de demander à quelqu'un d'autre de vous le dire; ce code peut vous aider:

public string GetPublicIP()
{
    String direction = "";
    WebRequest request = WebRequest.Create("http://checkip.dyndns.org/");
    using (WebResponse response = request.GetResponse())
    using (StreamReader stream = new StreamReader(response.GetResponseStream()))
    {
        direction = stream.ReadToEnd();
    }

    //Search for the ip in the html
    int first = direction.IndexOf("Address: ") + 9;
    int last = direction.LastIndexOf("</body>");
    direction = direction.Substring(first, last - first);

    return direction;
}
ezgar
la source
20
Savez-vous que votre exemple de code a été mentionné dans la question 13 Vingt questions C # expliquées de la Microsoft Academy? Le présentateur s'excuse d'avoir volé votre code. À partir de 8h30. Regardez ça . :)
Erwin Rooijakkers
4
Malheureusement, le lien est mort.
Barry Guvenkaya
Nouveau lien au cas où quelqu'un voudrait le voir
Kimmax
1
Veuillez utiliser le lien ipof.in/txt afin que vous puissiez obtenir l'adresse IP directement sans tout le code d'analyse HTML
vivekv
82

Plus propre et une solution tout-en-un: D

//This returns the first IP4 address or null
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
Mohammed A. Fadil
la source
3
Problèmes avec ce code: * Il suppose qu'un ordinateur n'a qu'une seule adresse IP. Beaucoup en ont plusieurs. * Il ne prend en compte que les adresses IPV4. Ajoutez InterNetworkV6 pour inclure IPV6.
Robert Bratton
1
@RobertBratton, Merci pour votre replay. Le problème ne supposait pas une adresse IP multiple ou IPV6, avec de légères modifications à ce code, il peut gérer différents problèmes spécifiques.
Mohammed A. Fadil
50

Si vous ne pouvez pas compter sur l'obtention de votre adresse IP à partir d'un serveur DNS (ce qui m'est arrivé), vous pouvez utiliser l'approche suivante:

L'espace de noms System.Net.NetworkInformation contient une classe NetworkInterface , qui a une méthode statique GetAllNetworkInterfaces .

Cette méthode retournera toutes les "interfaces réseau" sur votre machine, et il y en a généralement un certain nombre, même si vous n'avez qu'un adaptateur sans fil et / ou un matériel adaptateur Ethernet installé sur votre machine. Toutes ces interfaces réseau ont des adresses IP valides pour votre machine locale, bien que vous n'en vouliez probablement qu'une seule.

Si vous recherchez une adresse IP, vous devrez filtrer la liste jusqu'à ce que vous puissiez identifier la bonne adresse. Vous aurez probablement besoin de faire quelques expériences, mais j'ai réussi avec l'approche suivante:

  • Filtrez toutes les interfaces réseau qui sont inactives en vérifiant OperationalStatus == OperationalStatus.Up. Cela exclura votre adaptateur Ethernet physique, par exemple, si vous n'avez pas de câble réseau branché.

Pour chaque NetworkInterface, vous pouvez obtenir un objet IPInterfaceProperties à l'aide de la méthode GetIPProperties , et à partir d'un objet IPInterfaceProperties, vous pouvez accéder à la propriété UnicastAddresses pour une liste d' objets UnicastIPAddressInformation .

  • Filtrer les adresses de monodiffusion non préférées en recherchant DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred
  • Filtrez les adresses "virtuelles" en vérifiant AddressPreferredLifetime != UInt32.MaxValue.

À ce stade, je prends l'adresse de la première adresse unicast (le cas échéant) qui correspond à tous ces filtres.

ÉDITER:

[code révisé le 16 mai 2018 pour inclure les conditions mentionnées dans le texte ci-dessus pour l'état de détection d'adresse en double et la durée de vie préférée]

L'exemple ci-dessous illustre le filtrage basé sur l'état opérationnel, la famille d'adresses, à l'exclusion de l'adresse de bouclage (127.0.0.1), l'état de détection des adresses en double et la durée de vie préférée.

static IEnumerable<IPAddress> GetLocalIpAddresses()
{
    // Get the list of network interfaces for the local computer.
    var adapters = NetworkInterface.GetAllNetworkInterfaces();

    // Return the list of local IPv4 addresses excluding the local
    // host, disconnected, and virtual addresses.
    return (from adapter in adapters
            let properties = adapter.GetIPProperties()
            from address in properties.UnicastAddresses
            where adapter.OperationalStatus == OperationalStatus.Up &&
                  address.Address.AddressFamily == AddressFamily.InterNetwork &&
                  !address.Equals(IPAddress.Loopback) &&
                  address.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred &&
                  address.AddressPreferredLifetime != UInt32.MaxValue
            select address.Address);
}
Apprenti du Dr Wily
la source
2
Dans ce cas particulier, l'OP voulait voir son adresse IP externe, donc la solution DNS est probablement la voie à suivre. Mais pour itérer les adresses IP locales, c'est l'approche que je recommande.
Matt Davis
3
Convenu que DNS est un moyen plus facile d'obtenir l'adresse IP. J'ai mentionné dans ma réponse que cette approche fonctionne lorsque votre DNS n'est pas fiable. J'ai utilisé cela dans un environnement où DNS était foiré de telle sorte que si vous déplaciez une machine d'un port Ethernet à un autre, DNS rapporterait toujours l'ancienne adresse IP, donc c'était presque inutile pour mes besoins.
Apprenti du Dr Wily le
J'apprécie toute la description, mais vous auriez dû également publier l'exemple de code.
Aidin
Excellent, merci. Notez qu'après la récente mise à jour de Windows, UnicastAddresses. La première hypothèse ne tient plus. Je dois maintenant vérifier tous les UnicastAddress pour chaque adaptateur avec un filtrage supplémentaire en utilisant AddressPreferredLifetime et DuplicateAddressDetectionStation (mentionné dans votre texte ci-dessus)
user3085342
37
WebClient webClient = new WebClient();
string IP = webClient.DownloadString("http://myip.ozymo.com/");
James
la source
ifconfig.me/ip ne fonctionne plus. Essayez plutôt api.ipify.org ou le lien dans le commentaire de Doug
Kenny83
16
using System.Net;

string host = Dns.GetHostName();
IPHostEntry ip = Dns.GetHostEntry(host);
Console.WriteLine(ip.AddressList[0].ToString());

Je viens de tester cela sur ma machine et cela fonctionne.

opedog
la source
3
il obtiendra votre adresse IP locale, et la question concerne l'IP externe ieIp avec lequel vous naviguez sur Internet ..
Sangram Nandkhile
15

Si vous voulez éviter d'utiliser DNS:

List<IPAddress> ipList = new List<IPAddress>();
foreach (var netInterface in NetworkInterface.GetAllNetworkInterfaces())
{
    foreach (var address in netInterface.GetIPProperties().UnicastAddresses)
    {
        if (address.Address.AddressFamily == AddressFamily.InterNetwork)
        {
            Console.WriteLine("found IP " + address.Address.ToString());
            ipList.Add(address.Address);
        }
    }
}
reza
la source
9

Ne comptez pas sur InterNetwork tout le temps car vous pouvez avoir plus d'un appareil qui utilise également IP4, ce qui gâcherait les résultats pour obtenir votre IP. Maintenant, si vous le souhaitez, vous pouvez simplement le copier et le consulter ou le mettre à jour à votre guise.

D'abord, j'obtiens l'adresse du routeur (passerelle) S'il revient que je suis connecté à une passerelle (ce qui signifie non connecté directement au modem sans fil ou non), alors nous avons notre adresse de passerelle comme IPAddress sinon nous avons un pointeur nul Référence IPAddress .

Ensuite, nous devons obtenir la liste des adresses IP de l'ordinateur. C'est là que les choses ne sont pas si difficiles car les routeurs (tous les routeurs) utilisent 4 octets (...). Les trois premiers sont les plus importants car tout ordinateur qui y est connecté aura l'adresse IP4 correspondant aux trois premiers octets. Ex: 192.168.0.1 est standard pour l'IP par défaut du routeur à moins qu'il ne soit modifié par l'administrateur de celui-ci. '192.168.0' ou quoi que ce soit, c'est ce que nous devons faire correspondre. Et c'est tout ce que j'ai fait dans la fonction IsAddressOfGateway. La raison de la correspondance de longueur est que toutes les adresses (qui ne concernent que l'ordinateur) n'ont pas la longueur de 4 octets. Si vous tapez netstat dans la cmd, vous constaterez que c'est vrai. Alors voilà. Oui, il faut un peu plus de travail pour vraiment obtenir ce que vous cherchez. Processus d'élimination. Et pour l'amour de Dieu, ne trouvez pas l'adresse en la cinglant, ce qui prend du temps car vous envoyez d'abord l'adresse à cingler, puis elle doit renvoyer le résultat. Non, travaillez directement avec les classes .Net qui traitent de votre environnement système et vous obtiendrez les réponses que vous recherchez quand cela ne concerne que votre ordinateur.

Maintenant, si vous êtes directement connecté à votre modem, le processus est presque le même car le modem est votre passerelle, mais le sous-masque n'est pas le même parce que vous obtenez les informations directement de votre serveur DNS via un modem et non masqué par le routeur servant le Internet pour vous, bien que vous puissiez toujours utiliser le même code car le dernier octet de l'IP attribué au modem est 1. Donc, si l'IP envoyée par le modem qui change est 111.111.111.1 ', vous obtiendrez 111.111.111. (Certains octet). Gardez à l'esprit que nous devons trouver les informations sur la passerelle, car il y a plus d'appareils qui traitent de la connectivité Internet que votre routeur et votre modem.

Maintenant, vous voyez pourquoi vous ne modifiez PAS les deux premiers octets 192 et 168 de votre routeur. Ceux-ci sont strictement distingués uniquement pour les routeurs et non pour l'utilisation d'Internet, ou nous aurions un problème grave avec le protocole IP et un double ping provoquant le crash de votre ordinateur. Image que l'IP de votre routeur assigné est 192.168.44.103 et que vous cliquez également sur un site avec cette IP. OMG! Votre ordinateur ne saura pas quoi envoyer. Crash juste là. Pour éviter ce problème, seuls les routeurs leur sont attribués et non pour une utilisation Internet. Laissez donc les deux premiers octets du routeur seuls.

static IPAddress FindLanAddress()
{
    IPAddress gateway = FindGetGatewayAddress();
    if (gateway == null)
        return null;

    IPAddress[] pIPAddress = Dns.GetHostAddresses(Dns.GetHostName());

    foreach (IPAddress address in pIPAddress)            {
        if (IsAddressOfGateway(address, gateway))
                return address;
    return null;
}
static bool IsAddressOfGateway(IPAddress address, IPAddress gateway)
{
    if (address != null && gateway != null)
        return IsAddressOfGateway(address.GetAddressBytes(),gateway.GetAddressBytes());
    return false;
}
static bool IsAddressOfGateway(byte[] address, byte[] gateway)
{
    if (address != null && gateway != null)
    {
        int gwLen = gateway.Length;
        if (gwLen > 0)
        {
            if (address.Length == gateway.Length)
            {
                --gwLen;
                int counter = 0;
                for (int i = 0; i < gwLen; i++)
                {
                    if (address[i] == gateway[i])
                        ++counter;
                }
                return (counter == gwLen);
            }
        }
    }
    return false;

}
static IPAddress FindGetGatewayAddress()
{
    IPGlobalProperties ipGlobProps = IPGlobalProperties.GetIPGlobalProperties();

    foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
    {
        IPInterfaceProperties ipInfProps = ni.GetIPProperties();
        foreach (GatewayIPAddressInformation gi in ipInfProps.GatewayAddresses)
            return gi.Address;
    }
    return null;
}
bvrwoo_3376
la source
1
Cela n'a pas de sens: foreach (GatewayIPAddressInformation gi dans ipInfProps.GatewayAddresses) return gi.Address;
Edwin Evans
3
Il n'y a aucune garantie que "tout ordinateur connecté à une passerelle aura l'adresse IP4 correspondant aux trois premiers octets". Cela dépend du masque de sous-réseau, qui peut contenir différentes combinaisons de bits. Et en outre, les octets de départ ne doivent pas nécessairement être "192.168", car décrit ici . Ce code ne fonctionnera que si le masque de sous-réseau l'est 255.255.255.0, et il le fera de manière assez compliquée IMO.
Groo
8

Je pensais simplement que j'ajouterais la mienne, une ligne (même s'il existe déjà de nombreuses autres réponses utiles).


string ipAddress = new WebClient().DownloadString("http://icanhazip.com");

bæltazor
la source
4
Notez que cela a une fuite de mémoire potentielle. Le WebClient n'est pas correctement éliminé. Au lieu de cela, utilisez: using (var client = new WebClient ()) {return client.DownloadString (" icanhazip.com /"). Trim () ; }
FOO
4

Pour obtenir l'adresse IP publique actuelle, il vous suffit de créer une page ASPX avec la ligne suivante sur l'événement de chargement de page:

Response.Write(HttpContext.Current.Request.UserHostAddress.ToString());
détecter l'adresse IP publique
la source
4

Si vous utilisez Intranet, vous pourrez obtenir l'adresse IP de la machine locale et sinon, vous obtiendrez une adresse IP externe avec ceci: Web:

//this will bring the IP for the current machine on browser
System.Web.HttpContext.Current.Request.UserHostAddress

Bureau:

//This one will bring all local IPs for the desired namespace
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
Guilherme Ferreira
la source
3
namespace NKUtilities 
{
    using System;
    using System.Net;
    using System.Net.Sockets;

    public class DNSUtility
    {
        public static int Main(string [] args)
        {
            string strHostName = "";
            try {

                if(args.Length == 0)
                {
                    // 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);
                }
                else
                {
                    // Otherwise, get the IP address of the host provided on the command line.
                    strHostName = args[0];
                }

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

            } 
            catch(SocketException se) 
            {
                Console.WriteLine("{0} ({1})", se.Message, strHostName);
                return -1;
            } 
            catch(Exception ex) 
            {
                Console.WriteLine("Error: {0}.", ex.Message);
                return -1;
            }
        }
    }
}

Regardez ici pour plus de détails.

Vous devez vous rappeler que votre ordinateur peut avoir plus d'une adresse IP (en fait, c'est toujours le cas) - alors laquelle êtes-vous après.

mfloryan
la source
2

Essaye ça:

 IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
 String MyIp = localIPs[0].ToString();
Le masque
la source
1
Cela renvoie un certain nombre d'adresses IP locales, dont l'une est l'adresse IPv4, mais il est difficile de trouver la bonne dans la liste.
Contango
1

Peut-être que par IP externe, vous pouvez envisager (si vous êtes dans un contexte de serveur Web) d'utiliser ce

Request.ServerVariables["LOCAL_ADDR"];

Je posais la même question que vous et je l'ai trouvée dans cet article stackoverflow.

Ça a marché pour moi.

Juan Calero
la source
1
namespace NKUtilities 
{
    using System;
    using System.Net;

    public class DNSUtility
    {
        public static int Main (string [] args)
        {

          String strHostName = new String ("");
          if (args.Length == 0)
          {
              // 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);
          }
          else
          {
              strHostName = args[0];
          }

          // Then using host name, get the IP address list..
          IPHostEntry ipEntry = DNS.GetHostByName (strHostName);
          IPAddress [] addr = ipEntry.AddressList;

          for (int i = 0; i < addr.Length; i++)
          {
              Console.WriteLine ("IP Address {0}: {1} ", i, addr[i].ToString ());
          }
          return 0;
        }    
     }
}
naani
la source
1
using System;
using System.Net;

namespace IPADDRESS
{
    class Program
    {
        static void Main(string[] args)
        {
            String strHostName = string.Empty;
            if (args.Length == 0)
            {                
                /* First get the host name of local machine.*/
                strHostName = Dns.GetHostName();
                Console.WriteLine("Local Machine's Host Name: " + strHostName);
            }
            else
            {
                strHostName = args[0];
            }
            /* Then using host name, get the IP address list..*/
            IPHostEntry ipEntry = Dns.GetHostByName(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();
        }
    }
}
sundram
la source
1
return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);

Simple ligne de code unique qui renvoie la première adresse IPV4 interne ou null s'il n'y en a pas. Ajouté comme commentaire ci-dessus, mais peut être utile à quelqu'un (certaines solutions ci-dessus renverront plusieurs adresses qui nécessitent un filtrage supplémentaire).

Il est également facile de retourner en boucle au lieu de null, je suppose avec:

return Dns.GetHostEntry(Dns.GetHostName()).AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork) ?? new IPAddress( new byte[] {127, 0, 0, 1} );
Wolf5370
la source
1
Et alors IPAddress.Loopback? :)
CodeTherapist
1

Pour trouver la liste d'adresses IP, j'ai utilisé cette solution

public static IEnumerable<string> GetAddresses()
{
    var host = Dns.GetHostEntry(Dns.GetHostName());
    return (from ip in host.AddressList where ip.AddressFamily == AddressFamily.lo select ip.ToString()).ToList();
}

Mais j'aime personnellement la solution ci-dessous pour obtenir une adresse IP locale valide

public static IPAddress GetIPAddress(string hostName)
{
    Ping ping = new Ping();
    var replay = ping.Send(hostName);

    if (replay.Status == IPStatus.Success)
    {
        return replay.Address;
    }
    return null;
 }

public static void Main()
{
    Console.WriteLine("Local IP Address: " + GetIPAddress(Dns.GetHostName()));
    Console.WriteLine("Google IP:" + GetIPAddress("google.com");
    Console.ReadLine();
}
Ravi Shankar
la source
1

La solution LINQ:

Dns.GetHostEntry(Dns.GetHostName()).AddressList.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork).Select(ip => ip.ToString()).FirstOrDefault() ?? ""
Serge
la source
1

Voici comment je l'ai résolu. Je sais que si vous avez plusieurs interfaces physiques, cela pourrait ne pas sélectionner l'éth exact que vous souhaitez.

private string FetchIP()
{
    //Get all IP registered
    List<string> IPList = new List<string>();
    IPHostEntry host;
    host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (IPAddress ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork)
        {
            IPList.Add(ip.ToString());
        }
    }

    //Find the first IP which is not only local
    foreach (string a in IPList)
    {
        Ping p = new Ping();
        string[] b = a.Split('.');
        string ip2 = b[0] + "." + b[1] + "." + b[2] + ".1";
        PingReply t = p.Send(ip2);
        p.Dispose();
        if (t.Status == IPStatus.Success && ip2 != a)
        {
            return a;
        }
    }
    return null;
}
Thomas Andreè Wang
la source
1

La question ne dit pas ASP.NET MVC mais je laisse juste ceci ici de toute façon:

Request.UserHostAddress
Barry Guvenkaya
la source
1

Obtenez toutes les adresses IP sous forme de chaînes à l'aide de LINQ:

using System.Linq;
using System.Net.NetworkInformation;
using System.Net.Sockets;
...
string[] allIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
    .SelectMany(c=>c.GetIPProperties().UnicastAddresses
        .Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork)
        .Select(d=>d.Address.ToString())
    ).ToArray();

POUR FILTRER LES PERSONNES PRIVÉES ...

Définissez d'abord une méthode d'extension IsPrivate():

public static class IPAddressExtensions
{
    // Collection of private CIDRs (IpAddress/Mask) 
    private static Tuple<int, int>[] _privateCidrs = new []{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"}
        .Select(c=>Tuple.Create(BitConverter.ToInt32(IPAddress
                                    .Parse(c.Split('/')[0]).GetAddressBytes(), 0)
                              , IPAddress.HostToNetworkOrder(-1 << (32-int.Parse(c.Split('/')[1])))))
        .ToArray();
    public static bool IsPrivate(this IPAddress ipAddress)
    {
        int ip = BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0);
        return _privateCidrs.Any(cidr=>(ip & cidr.Item2)==(cidr.Item1 & cidr.Item2));           
    }
}

... Et puis utilisez-le pour filtrer les adresses IP privées:

string[] publicIpAddresses = NetworkInterface.GetAllNetworkInterfaces()
    .SelectMany(c=>c.GetIPProperties().UnicastAddresses
        .Where(d=>d.Address.AddressFamily == AddressFamily.InterNetwork
            && !d.Address.IsPrivate() // Filter out private ones
        )
        .Select(d=>d.Address.ToString())
    ).ToArray();
Diego
la source
1

Cela fonctionne pour moi ... et devrait être plus rapide dans la plupart des cas (sinon tous) que d'interroger un serveur DNS. Merci à Dr. Wily's Apprentice ( ici ).

// ************************************************************************
/// <summary>
/// Will search for the an active NetworkInterafce that has a Gateway, otherwise
/// it will fallback to try from the DNS which is not safe.
/// </summary>
/// <returns></returns>
public static NetworkInterface GetMainNetworkInterface()
{
    List<NetworkInterface> candidates = new List<NetworkInterface>();

    if (NetworkInterface.GetIsNetworkAvailable())
    {
        NetworkInterface[] NetworkInterfaces =
            NetworkInterface.GetAllNetworkInterfaces();

        foreach (
            NetworkInterface ni in NetworkInterfaces)
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
                candidates.Add(ni);
        }
    }

    if (candidates.Count == 1)
    {
        return candidates[0];
    }

    // Accoring to our tech, the main NetworkInterface should have a Gateway 
    // and it should be the ony one with a gateway.
    if (candidates.Count > 1)
    {
        for (int n = candidates.Count - 1; n >= 0; n--)
        {
            if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
            {
                candidates.RemoveAt(n);
            }
        }

        if (candidates.Count == 1)
        {
            return candidates[0];
        }
    }

    // Fallback to try by getting my ipAdress from the dns
    IPAddress myMainIpAdress = null;
    IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
    foreach (IPAddress ip in host.AddressList)
    {
        if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
        {
            myMainIpAdress = ip;
            break;
        }
    }

    if (myMainIpAdress != null)
    {
        NetworkInterface[] NetworkInterfaces =
            NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface ni in NetworkInterfaces)
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
            {
                IPInterfaceProperties props = ni.GetIPProperties();
                foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                {
                    if (ai.Address.Equals(myMainIpAdress))
                    {
                        return ni;
                    }
                }
            }
        }
    }

    return null;
}

// ******************************************************************
/// <summary>
/// AddressFamily.InterNetwork = IPv4
/// Thanks to Dr. Wilys Apprentice at
/// http://stackoverflow.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
/// using System.Net.NetworkInformation;
/// </summary>
/// <param name="mac"></param>
/// <param name="addressFamily">AddressFamily.InterNetwork = IPv4,  AddressFamily.InterNetworkV6 = IPv6</param>
/// <returns></returns>
public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
{
    NetworkInterface[] NetworkInterfaces =
        NetworkInterface.GetAllNetworkInterfaces();

    foreach (NetworkInterface ni in NetworkInterfaces)
    {
        if (ni.GetPhysicalAddress().Equals(mac))
        {
            if (ni.OperationalStatus == OperationalStatus.Up)
            {
                IPInterfaceProperties props = ni.GetIPProperties();
                foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                {
                    if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
                    {
                        if (ai.Address.AddressFamily == addressFamily)
                        {
                            return ai.Address;
                        }
                    }
                }
            }
        }
    }

    return null;
}

// ******************************************************************
/// <summary>
/// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call 
/// '?.ToString() ?? ""' on the result.
/// </summary>
/// <returns></returns>
public static IPAddress GetMyInternetIpAddress()
{
    NetworkInterface ni = GetMainNetworkInterface();
    IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
    if (ipAddress == null) // could it be possible ?
    {
        ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
    }

    return ipAddress;
}

// ******************************************************************

Tout comme référence, c'est le code de classe complet où je l'ai défini:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

namespace TcpMonitor
{
    /*
        Usage:
                var cons = TcpHelper.GetAllTCPConnections();
                foreach (TcpHelper.MIB_TCPROW_OWNER_PID c in cons) ...
    */

    public class NetHelper
    {
        [DllImport("iphlpapi.dll", SetLastError = true)]
        static extern uint GetExtendedUdpTable(IntPtr pUdpTable, ref int dwOutBufLen, bool sort, int ipVersion, UDP_TABLE_CLASS tblClass, uint reserved = 0);

        public enum UDP_TABLE_CLASS
        {
            UDP_TABLE_BASIC,
            UDP_TABLE_OWNER_PID,
            UDP_TABLE_OWNER_MODULE
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDPTABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_UDPROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDPROW_OWNER_PID
        {
            public uint localAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDP6TABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_UDP6ROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_UDP6ROW_OWNER_PID
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] localAddr;
            public uint localScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint owningPid;
            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr, localScopeId); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }
        }

        public static List<MIB_UDPROW_OWNER_PID> GetAllUDPConnections()
        {
            return GetUDPConnections<MIB_UDPROW_OWNER_PID, MIB_UDPTABLE_OWNER_PID> (AF_INET);
        }

        public static List<MIB_UDP6ROW_OWNER_PID> GetAllUDPv6Connections()
        {
            return GetUDPConnections<MIB_UDP6ROW_OWNER_PID, MIB_UDP6TABLE_OWNER_PID>(AF_INET6);
        }

        private static List<IPR> GetUDPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
        {
            List<IPR> result = null;

            IPR[] tableRows = null;
            int buffSize = 0;

            var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");

            // how much memory do we need?
            uint ret = GetExtendedUdpTable(IntPtr.Zero, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
            IntPtr udpTablePtr = Marshal.AllocHGlobal(buffSize);

            try
            {
                ret = GetExtendedUdpTable(udpTablePtr, ref buffSize, true, ipVersion, UDP_TABLE_CLASS.UDP_TABLE_OWNER_PID);
                if (ret != 0)
                    return new List<IPR>();

                // get the number of entries in the table
                IPT table = (IPT)Marshal.PtrToStructure(udpTablePtr, typeof(IPT));
                int rowStructSize = Marshal.SizeOf(typeof(IPR));
                uint numEntries = (uint)dwNumEntriesField.GetValue(table);

                // buffer we will be returning
                tableRows = new IPR[numEntries];

                IntPtr rowPtr = (IntPtr)((long)udpTablePtr + 4);
                for (int i = 0; i < numEntries; i++)
                {
                    IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
                    tableRows[i] = tcpRow;
                    rowPtr = (IntPtr)((long)rowPtr + rowStructSize);   // next entry
                }
            }
            finally
            {
                result = tableRows?.ToList() ?? new List<IPR>();

                // Free the Memory
                Marshal.FreeHGlobal(udpTablePtr);
            }

            return result;
        }

        [DllImport("iphlpapi.dll", SetLastError = true)]
        static extern uint GetExtendedTcpTable(IntPtr pTcpTable, ref int dwOutBufLen, bool sort, int ipVersion, TCP_TABLE_CLASS tblClass, uint reserved = 0);



        public enum MIB_TCP_STATE
        {
            MIB_TCP_STATE_CLOSED = 1,
            MIB_TCP_STATE_LISTEN = 2,
            MIB_TCP_STATE_SYN_SENT = 3,
            MIB_TCP_STATE_SYN_RCVD = 4,
            MIB_TCP_STATE_ESTAB = 5,
            MIB_TCP_STATE_FIN_WAIT1 = 6,
            MIB_TCP_STATE_FIN_WAIT2 = 7,
            MIB_TCP_STATE_CLOSE_WAIT = 8,
            MIB_TCP_STATE_CLOSING = 9,
            MIB_TCP_STATE_LAST_ACK = 10,
            MIB_TCP_STATE_TIME_WAIT = 11,
            MIB_TCP_STATE_DELETE_TCB = 12
        }

        public enum TCP_TABLE_CLASS
        {
            TCP_TABLE_BASIC_LISTENER,
            TCP_TABLE_BASIC_CONNECTIONS,
            TCP_TABLE_BASIC_ALL,
            TCP_TABLE_OWNER_PID_LISTENER,
            TCP_TABLE_OWNER_PID_CONNECTIONS,
            TCP_TABLE_OWNER_PID_ALL,
            TCP_TABLE_OWNER_MODULE_LISTENER,
            TCP_TABLE_OWNER_MODULE_CONNECTIONS,
            TCP_TABLE_OWNER_MODULE_ALL
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPTABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_TCPROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCP6TABLE_OWNER_PID
        {
            public uint dwNumEntries;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 1)]
            public MIB_TCP6ROW_OWNER_PID[] table;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCPROW_OWNER_PID
        {
            public uint state;
            public uint localAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            public uint remoteAddr;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] remotePort;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr); }
            }

            public ushort LocalPort
            {
                get
                {
                    return BitConverter.ToUInt16(new byte[2] { localPort[1], localPort[0] }, 0);
                }
            }

            public IPAddress RemoteAddress
            {
                get { return new IPAddress(remoteAddr); }
            }

            public ushort RemotePort
            {
                get
                {
                    return BitConverter.ToUInt16(new byte[2] { remotePort[1], remotePort[0] }, 0);
                }
            }

            public MIB_TCP_STATE State
            {
                get { return (MIB_TCP_STATE)state; }
            }
        }


        [StructLayout(LayoutKind.Sequential)]
        public struct MIB_TCP6ROW_OWNER_PID
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] localAddr;
            public uint localScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] localPort;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
            public byte[] remoteAddr;
            public uint remoteScopeId;
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
            public byte[] remotePort;
            public uint state;
            public uint owningPid;

            public uint ProcessId
            {
                get { return owningPid; }
            }

            public long LocalScopeId
            {
                get { return localScopeId; }
            }

            public IPAddress LocalAddress
            {
                get { return new IPAddress(localAddr, LocalScopeId); }
            }

            public ushort LocalPort
            {
                get { return BitConverter.ToUInt16(localPort.Take(2).Reverse().ToArray(), 0); }
            }

            public long RemoteScopeId
            {
                get { return remoteScopeId; }
            }

            public IPAddress RemoteAddress
            {
                get { return new IPAddress(remoteAddr, RemoteScopeId); }
            }

            public ushort RemotePort
            {
                get { return BitConverter.ToUInt16(remotePort.Take(2).Reverse().ToArray(), 0); }
            }

            public MIB_TCP_STATE State
            {
                get { return (MIB_TCP_STATE)state; }
            }
        }


        public const int AF_INET = 2;    // IP_v4 = System.Net.Sockets.AddressFamily.InterNetwork
        public const int AF_INET6 = 23;  // IP_v6 = System.Net.Sockets.AddressFamily.InterNetworkV6

        public static Task<List<MIB_TCPROW_OWNER_PID>> GetAllTCPConnectionsAsync()
        {
            return Task.Run(() => GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET));
        }

        public static List<MIB_TCPROW_OWNER_PID> GetAllTCPConnections()
        {
            return GetTCPConnections<MIB_TCPROW_OWNER_PID, MIB_TCPTABLE_OWNER_PID>(AF_INET);
        }

        public static Task<List<MIB_TCP6ROW_OWNER_PID>> GetAllTCPv6ConnectionsAsync()
        {
            return Task.Run(()=>GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6));
        }

        public static List<MIB_TCP6ROW_OWNER_PID> GetAllTCPv6Connections()
        {
            return GetTCPConnections<MIB_TCP6ROW_OWNER_PID, MIB_TCP6TABLE_OWNER_PID>(AF_INET6);
        }

        private static List<IPR> GetTCPConnections<IPR, IPT>(int ipVersion)//IPR = Row Type, IPT = Table Type
        {
            List<IPR> result = null;

            IPR[] tableRows = null;
            int buffSize = 0;

            var dwNumEntriesField = typeof(IPT).GetField("dwNumEntries");

            // how much memory do we need?
            uint ret = GetExtendedTcpTable(IntPtr.Zero, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
            IntPtr tcpTablePtr = Marshal.AllocHGlobal(buffSize);

            try
            {
                ret = GetExtendedTcpTable(tcpTablePtr, ref buffSize, true, ipVersion, TCP_TABLE_CLASS.TCP_TABLE_OWNER_PID_ALL);
                if (ret != 0)
                    return new List<IPR>();

                // get the number of entries in the table
                IPT table = (IPT)Marshal.PtrToStructure(tcpTablePtr, typeof(IPT));
                int rowStructSize = Marshal.SizeOf(typeof(IPR));
                uint numEntries = (uint)dwNumEntriesField.GetValue(table);

                // buffer we will be returning
                tableRows = new IPR[numEntries];

                IntPtr rowPtr = (IntPtr)((long)tcpTablePtr + 4);
                for (int i = 0; i < numEntries; i++)
                {
                    IPR tcpRow = (IPR)Marshal.PtrToStructure(rowPtr, typeof(IPR));
                    tableRows[i] = tcpRow;
                    rowPtr = (IntPtr)((long)rowPtr + rowStructSize);   // next entry
                }
            }
            finally
            {
                result = tableRows?.ToList() ?? new List<IPR>();

                // Free the Memory
                Marshal.FreeHGlobal(tcpTablePtr);
            }

            return result;
        }

        public static string GetTcpStateName(MIB_TCP_STATE state)
        {
            switch (state)
            {
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSED:
                    return "Closed";
                case MIB_TCP_STATE.MIB_TCP_STATE_LISTEN:
                    return "Listen";
                case MIB_TCP_STATE.MIB_TCP_STATE_SYN_SENT:
                    return "SynSent";
                case MIB_TCP_STATE.MIB_TCP_STATE_SYN_RCVD:
                    return "SynReceived";
                case MIB_TCP_STATE.MIB_TCP_STATE_ESTAB:
                    return "Established";
                case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT1:
                    return "FinWait 1";
                case MIB_TCP_STATE.MIB_TCP_STATE_FIN_WAIT2:
                    return "FinWait 2";
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSE_WAIT:
                    return "CloseWait";
                case MIB_TCP_STATE.MIB_TCP_STATE_CLOSING:
                    return "Closing";
                case MIB_TCP_STATE.MIB_TCP_STATE_LAST_ACK:
                    return "LastAck";
                case MIB_TCP_STATE.MIB_TCP_STATE_TIME_WAIT:
                    return "TimeWait";
                case MIB_TCP_STATE.MIB_TCP_STATE_DELETE_TCB:
                    return "DeleteTCB";
                default:
                    return ((int)state).ToString();
            }
        }

        private static readonly ConcurrentDictionary<string, string> DicOfIpToHostName = new ConcurrentDictionary<string, string>();

        public const string UnknownHostName = "Unknown";

        // ******************************************************************
        public static string GetHostName(IPAddress ipAddress)
        {
            return GetHostName(ipAddress.ToString());
        }

        // ******************************************************************
        public static string GetHostName(string ipAddress)
        {
            string hostName = null;

            if (!DicOfIpToHostName.TryGetValue(ipAddress, out hostName))
            {
                try
                {
                    if (ipAddress == "0.0.0.0" || ipAddress == "::")
                    {
                        hostName = ipAddress;
                    }
                    else
                    {
                        hostName = Dns.GetHostEntry(ipAddress).HostName;
                    }
                }
                catch (Exception ex)
                {
                    Debug.Print(ex.ToString());
                    hostName = UnknownHostName;
                }

                DicOfIpToHostName[ipAddress] = hostName;
            }

            return hostName;
        }

        // ************************************************************************
        /// <summary>
        /// Will search for the an active NetworkInterafce that has a Gateway, otherwise
        /// it will fallback to try from the DNS which is not safe.
        /// </summary>
        /// <returns></returns>
        public static NetworkInterface GetMainNetworkInterface()
        {
            List<NetworkInterface> candidates = new List<NetworkInterface>();

            if (NetworkInterface.GetIsNetworkAvailable())
            {
                NetworkInterface[] NetworkInterfaces =
                    NetworkInterface.GetAllNetworkInterfaces();

                foreach (
                    NetworkInterface ni in NetworkInterfaces)
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                        candidates.Add(ni);
                }
            }

            if (candidates.Count == 1)
            {
                return candidates[0];
            }

            // Accoring to our tech, the main NetworkInterface should have a Gateway 
            // and it should be the ony one with a gateway.
            if (candidates.Count > 1)
            {
                for (int n = candidates.Count - 1; n >= 0; n--)
                {
                    if (candidates[n].GetIPProperties().GatewayAddresses.Count == 0)
                    {
                        candidates.RemoveAt(n);
                    }
                }

                if (candidates.Count == 1)
                {
                    return candidates[0];
                }
            }

            // Fallback to try by getting my ipAdress from the dns
            IPAddress myMainIpAdress = null;
            IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == AddressFamily.InterNetwork) // Get the first IpV4
                {
                    myMainIpAdress = ip;
                    break;
                }
            }

            if (myMainIpAdress != null)
            {
                NetworkInterface[] NetworkInterfaces =
                    NetworkInterface.GetAllNetworkInterfaces();

                foreach (NetworkInterface ni in NetworkInterfaces)
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                    {
                        IPInterfaceProperties props = ni.GetIPProperties();
                        foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                        {
                            if (ai.Address.Equals(myMainIpAdress))
                            {
                                return ni;
                            }
                        }
                    }
                }
            }

            return null;
        }

        // ******************************************************************
        /// <summary>
        /// AddressFamily.InterNetwork = IPv4
        /// Thanks to Dr. Wilys Apprentice at
        /// http://stackoverflow.com/questions/1069103/how-to-get-the-ip-address-of-the-server-on-which-my-c-sharp-application-is-runni
        /// using System.Net.NetworkInformation;
        /// </summary>
        /// <param name="mac"></param>
        /// <param name="addressFamily">AddressFamily.InterNetwork = IPv4,  AddressFamily.InterNetworkV6 = IPv6</param>
        /// <returns></returns>
        public static IPAddress GetIpFromMac(PhysicalAddress mac, AddressFamily addressFamily = AddressFamily.InterNetwork)
        {
            NetworkInterface[] NetworkInterfaces =
                NetworkInterface.GetAllNetworkInterfaces();

            foreach (NetworkInterface ni in NetworkInterfaces)
            {
                if (ni.GetPhysicalAddress().Equals(mac))
                {
                    if (ni.OperationalStatus == OperationalStatus.Up)
                    {
                        IPInterfaceProperties props = ni.GetIPProperties();
                        foreach (UnicastIPAddressInformation ai in props.UnicastAddresses)
                        {
                            if (ai.DuplicateAddressDetectionState == DuplicateAddressDetectionState.Preferred)
                            {
                                if (ai.Address.AddressFamily == addressFamily)
                                {
                                    return ai.Address;
                                }
                            }
                        }
                    }
                }
            }

            return null;
        }

        // ******************************************************************
        /// <summary>
        /// Return the best guess of main ipAdress. To get it in the form aaa.bbb.ccc.ddd just call 
        /// '?.ToString() ?? ""' on the result.
        /// </summary>
        /// <returns></returns>
        public static IPAddress GetMyInternetIpAddress()
        {
            NetworkInterface ni = GetMainNetworkInterface();
            IPAddress ipAddress = GetIpFromMac(ni.GetPhysicalAddress());
            if (ipAddress == null) // could it be possible ?
            {
                ipAddress = GetIpFromMac(ni.GetPhysicalAddress(), AddressFamily.InterNetworkV6);
            }

            return ipAddress;
        }

        // ******************************************************************
        public static bool IsBroadcastAddress(IPAddress ipAddress)
        {
            if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                return ipAddress.GetAddressBytes()[3] == 255;
            }

            if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
            {
                return false; // NO broadcast in IPv6
            }

            return false;
        }

        // ******************************************************************
        public static bool IsMulticastAddress(IPAddress ipAddress)
        {
            if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
            {
                // Source: https://technet.microsoft.com/en-us/library/cc772041(v=ws.10).aspx
                return ipAddress.GetAddressBytes()[0] >= 224 && ipAddress.GetAddressBytes()[0] <= 239;
            }

            if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
            {
                return ipAddress.IsIPv6Multicast;
            }

            return false;
        }

        // ******************************************************************

    }
}
Eric Ouellet
la source
1

Encore une autre façon d'obtenir votre adresse IP publique est d'utiliser le resolve1.opendns.comserveur d' OpenDNS avecmyip.opendns.com comme demande.

Sur la ligne de commande, c'est:

  nslookup myip.opendns.com resolver1.opendns.com

Ou en C # en utilisant le nuget DNSClient:

  var lookup = new LookupClient(new IPAddress(new byte[] { 208, 67, 222, 222 }));
  var result = lookup.Query("myip.opendns.com", QueryType.ANY);

C'est un peu plus propre que de toucher les points de terminaison http et d'analyser les réponses.

Ian Mercer
la source
0

Et c'est pour obtenir toutes les adresses IP locales au format csv dans VB.NET

Imports System.Net
Imports System.Net.Sockets

Function GetIPAddress() As String
    Dim ipList As List(Of String) = New List(Of String)
    Dim host As IPHostEntry
    Dim localIP As String = "?"
    host = Dns.GetHostEntry(Dns.GetHostName())
    For Each ip As IPAddress In host.AddressList
        If ip.AddressFamily = AddressFamily.InterNetwork Then
            localIP = ip.ToString()
            ipList.Add(localIP)
        End If
    Next
    Dim ret As String = String.Join(",", ipList.ToArray)
    Return ret
End Function
Saurabh Kumar
la source
0

Pour obtenir l'adresse IP distante de la manière la plus rapide 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: (ce qui est recommandé) est qu'il 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, il obtiendra toujours votre adresse IP distante en 0-2 secondes en fonction de 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;
}
SSpoke
la source
Pourquoi le downvote? vous ne pouvez pas trouver une réponse plus rapidement ou mieux que cela .. l'initialisation du WebClient à chaque fois a un gros délai de surcharge sans aucun moyen de le contourner.
SS a parlé