376 votes

Obtenir l'adresse IP locale

Sur Internet, il existe plusieurs sites qui vous montrent comment obtenir une adresse IP. Et beaucoup d'entre eux ressemblent à cet exemple :

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

Avec cet exemple, j'obtiens plusieurs adresses IP, mais je ne suis intéressé que par celle que le routeur attribue à l'ordinateur qui exécute le programme : l'IP que je donnerais à quelqu'un s'il souhaite accéder à un dossier partagé dans mon ordinateur par exemple.

Si je ne suis pas connecté à un réseau et que je suis connecté à l'internet directement via un modem sans routeur, j'aimerais obtenir une erreur. Comment puis-je voir si mon ordinateur est connecté à un réseau avec C# et s'il l'est, obtenir l'adresse IP du réseau local.

2 votes

If I am not connected to a network and I am connected to the internet Cette déclaration semble contradictoire. Essayez-vous de déterminer si votre ordinateur est connecté à un réseau local privé ou à l'Internet ?

6 votes

A titre d'avertissement : Un ordinateur peut avoir plus d'une interface IP, par exemple un LAN et un WiFi. Si vous liez un service à un élément matériel particulier (par exemple le réseau local), vous avez besoin de l'adresse IP du réseau local. La plupart des exemples suivants renverront la "première" ou la "dernière" adresse IP trouvée. Si vous avez plus de 2 adresses IP, votre programme peut fonctionner dans 50% des cas, en fonction de l'ordre aléatoire dans lequel le système d'exploitation renvoie les adresses IP.

0 votes

@MarkLakata J'ai pensé au même problème. La fonction dans ma réponse ci-dessous s'en chargera. Vous pouvez spécifier le type d'interface réseau à partir duquel vous souhaitez obtenir l'adresse IP.

551voto

Mrchief Points 25418

Pour obtenir l'adresse IP locale :

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

Pour vérifier si vous êtes connecté ou non :

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

43 votes

Ne fonctionnera pas si vous utilisez des trucs comme vm virtual box, genymotion, etc.

6 votes

Je suis d'accord avec PaulEffect. Non seulement cette méthode est mauvaise pour les cartes réseau multiples, mais en plus, elle ne fait pas la différence entre les adresses IP v6 et IP v4.

26 votes

@John AddressFamily.InterNetwork est IP v4 et AddressFamily.InterNetworkV6 est IP v6

147voto

compman2408 Points 116

Je sais qu'il s'agit peut-être d'un coup de pied dans un cheval mort, mais peut-être que cela peut aider quelqu'un. J'ai cherché partout un moyen de trouver mon adresse IP locale, mais partout où j'ai trouvé il est dit d'utiliser.. :

Dns.GetHostEntry(Dns.GetHostName());

Je n'aime pas du tout cette méthode car elle permet de récupérer toutes les adresses attribuées à votre ordinateur. Si vous avez plusieurs interfaces réseau (ce qui est le cas de presque tous les ordinateurs aujourd'hui), vous n'avez aucune idée de quelle adresse correspond à quelle interface réseau. Après avoir fait un tas de recherches, j'ai créé une fonction qui utilise la classe NetworkInterface et en extrait les informations. De cette façon, je peux savoir quel type d'interface c'est (Ethernet, sans fil, loopback, tunnel, etc.), si elle est active ou non, et bien d'autres choses encore.

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

Maintenant pour obtenir l'adresse IPv4 de votre appel d'interface réseau Ethernet :

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Ou votre interface sans fil :

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Si vous essayez d'obtenir une adresse IPv4 pour une interface sans fil, mais que votre ordinateur n'a pas de carte sans fil installée, il renverra simplement une chaîne vide. Même chose pour l'interface Ethernet.

J'espère que cela aidera quelqu'un ! :-)

EDITAR:

Il a été signalé (merci @NasBanov) que même si cette fonction extrait l'adresse IP d'une manière bien plus efficace que l'utilisation de la fonction Dns.GetHostEntry(Dns.GetHostName()) il ne supporte pas très bien les interfaces multiples du même type ou les adresses IP multiples sur une seule interface. Elle ne renvoie qu'une seule adresse IP alors qu'il peut y avoir plusieurs adresses attribuées. Pour renvoyer TOUTES ces adresses assignées, vous pouvez simplement manipuler la fonction originale pour qu'elle renvoie toujours un tableau au lieu d'une seule chaîne de caractères. Par exemple :

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

Maintenant, cette fonction renverra TOUTES les adresses assignées pour un type d'interface spécifique. Pour obtenir une seule chaîne de caractères, vous pouvez utiliser la fonction .FirstOrDefault() pour retourner le premier élément du tableau ou, s'il est vide, retourner une chaîne vide.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();

8 votes

C'est une meilleure solution car il n'y a pas de possibilité d'utiliser le DNS dans de nombreux endroits et les interfaces peuvent avoir plusieurs adresses IP. J'utilise également une méthode similaire.

0 votes

Le problème est que vous ne renvoyez qu'une seule adresse IP par interface... la dernière IP, foreach.

0 votes

@compman2408 - ce n'est pas vrai, une seule interface peut avoir plusieurs IP, voir fr.wikipedia.org/wiki/Multihoming#Variants pour tous les combos. L'exemple le plus évident est l'utilisation d'IPv4 et d'IPv6, mais dans le passé, j'ai vu un seul adaptateur Ethernet participer à plusieurs réseaux IPv4. C'est peut-être inhabituel, mais parfaitement légal. Par exemple, pour Windows, voir windowsnetworking.com/articles-tutoriels/Windows-2003/

120voto

Pure.Krome Points 28473

Refactoring du code de Mrcheif pour tirer profit de Linq (ie. .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);
}

:)

0 votes

J'ai quelques adresses IP en tant que "Inter Network" et cette solution fonctionne réellement et me donne la bonne. L'autre solution de Mrchief ne me donne que la dernière. Donc en fait, cette solution devrait être la bonne ;)

32 votes

@KeenoraFluffball - celui-ci vous donne la première, alors que celui-là vous donne la dernière (ou vice versa, cela dépend de la façon dont la liste est construite). Dans un cas comme dans l'autre, aucune des deux n'est correcte. Si vous disposez de plus d'une adresse IP, vous devez savoir quel réseau vous utilisez. Deviner en prenant la première ou la dernière n'est pas la bonne solution.

0 votes

Vous pouvez également inclure AddressFamily.InterNetworkV6.

25voto

KP_ Points 371

Je pense que l'utilisation de LINQ est plus facile :

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()

14 votes

Ce n'est pas LINQ, ce sont des méthodes d'extension et des lambdas. Il y a une différence.

12 votes

@Mark - Si vous n'ajoutez pas "using System.Linq ;", vous ne pouvez pas utiliser la méthode d'extension "First".

5 votes

C'est parce que la méthode d'extension est dans la classe Enumerable qui est dans l'espace de noms System.Linq. Ce n'est toujours pas LINQ.

7voto

Jordan Trainor Points 390

@mrcheif J'ai trouvé cette réponse aujourd'hui et elle a été très utile bien qu'elle ait retourné une mauvaise IP (pas à cause du code qui ne fonctionne pas) mais elle a donné une mauvaise IP de réseau internet lorsque vous avez des choses comme Himachi en cours d'exécution.

public static string localIPAddress()
{
    IPHostEntry host;
    string localIP = "";
    host = Dns.GetHostEntry(Dns.GetHostName());

    foreach (IPAddress ip in host.AddressList)
    {
        localIP = ip.ToString();

        string[] temp = localIP.Split('.');

        if (ip.AddressFamily == AddressFamily.InterNetwork && temp[0] == "192")
        {
            break;
        }
        else
        {
            localIP = null;
        }
    }

    return localIP;
}

2 votes

Vous voulez dire Logmein Hamachi ? Il s'agit d'une solution VPN qui manipule la pile réseau. De plus, étant donné qu'il s'agit d'un VPN, il semble raisonnable qu'il renvoie l'adresse IP attribuée au VPN lorsqu'il est connecté (ce n'est qu'une supposition).

2 votes

Complètement incertaine. Non seulement 192.0.0.0/8 ce n'est pas un test correct pour une adresse IP privée (il y a 3 gammes, toutes différentes de celle-ci), il peut très bien s'agir d'une gamme de réseau d'entreprise, donc pas vraiment "locale".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X