Obtenir l'adresse IP locale


301

Sur Internet, il existe plusieurs endroits 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 souhaite obtenir que celle que le routeur attribue à l'ordinateur exécutant le programme: l'adresse IP que je donnerais à quelqu'un s'il souhaite accéder à un dossier partagé sur mon ordinateur pour exemple.

Si je ne suis pas connecté à un réseau et que je suis connecté à Internet directement via un modem sans routeur, je voudrais obtenir une erreur. Comment puis-je voir si mon ordinateur est connecté à un réseau avec C # et si c'est pour obtenir l'adresse IP LAN.


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

4
Juste un avertissement: un ordinateur peut avoir plus d'une interface IP, par exemple un LAN et WiFi. Si vous liez un service à un matériel particulier (par exemple le LAN), vous avez besoin de l'IP du LAN. La plupart des exemples suivants renvoient la "première" ou "la dernière" adresse IP trouvée. Si vous avez plus de 2 adresses IP, votre programme peut fonctionner 50% du temps, selon l'ordre aléatoire du système d'exploitation renvoie les adresses IP.
Mark Lakata

@MarkLakata J'ai pensé au même problème. La fonction dans ma réponse ci-dessous le gérera. Vous pouvez spécifier le type d'interface réseau à partir de laquelle vous souhaitez l'adresse IP.
compman2408

3
Juste FTR, si vous recherchez Google ici pour Unity3D, c'est Network.player.ipAddress dans leur API
Fattie

@MarkLakata à proprement parler, la «première» ou «dernière» IP est la «bonne» IP, car le navigateur peut utiliser n'importe quelle IP disponible. Une bonne correction devrait probablement être de renvoyer chaque IP associée à la machine.
UncaAlby

Réponses:


457

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


29
ne fonctionnera pas si vous utilisez des trucs comme vm virtual box, genymotion, etc.
PauLEffect

5
D'accord avec PaulEffect. Non seulement cette méthode est mauvaise pour plusieurs cartes réseau, mais elle ne différencie pas non plus les adresses IP v6 et IP v4.
Max

16
@John AddressFamily.InterNetwork est IP v4 et AddressFamily.InterNetworkV6 est IP v6
Leonardo Xavier

J'utilise Geraldo H Answer, mais si quelqu'un l'utilise, vous voudrez peut-être supprimer toutes les ips qui se terminent par 1, il supprimera donc les ips par défaut de bouclage et de virtualbox / vmware
Leonardo Xavier

6
Il semble que vous utilisiez VMWare ou un autre logiciel de virtualisation. Le PO n'a pas demandé cela, donc je pense que voter contre à cause de cela est un peu dur. Si vous avez VMWare ou plusieurs cartes réseau, certaines des autres réponses fournissent déjà des indices à ce sujet.
Mrchief

218

Il existe un moyen plus précis lorsqu'il existe plusieurs adresses IP disponibles sur la machine locale. Connectun socket UDP et lire son point de terminaison local:

string localIP;
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
    socket.Connect("8.8.8.8", 65530);
    IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
    localIP = endPoint.Address.ToString();
}

Connect sur un socket UDP a l'effet suivant: il définit la destination de Send / Recv, rejette tous les paquets provenant d'autres adresses, et - ce que nous utilisons - transfère le socket dans l'état "connecté", définit ses champs appropriés. Cela comprend la vérification de l'existence de l'itinéraire vers la destination en fonction de la table de routage du système et la définition du point de terminaison local en conséquence. La dernière partie ne semble pas être officiellement documentée, mais elle ressemble à un trait intégral de l'API des sockets Berkeley (un effet secondaire de l'état "connecté" UDP) qui fonctionne de manière fiable dans Windows et Linux à travers les versions et les distributions.

Ainsi, cette méthode donnera l'adresse locale qui serait utilisée pour se connecter à l'hôte distant spécifié. Il n'y a pas de connexion réelle établie, l'IP distante spécifiée peut donc être inaccessible.


4
C'est la meilleure solution qui a fonctionné pour mes besoins. Dans ma situation, j'ai plusieurs cartes réseaux et quelques connexions sans fil. J'avais besoin d'obtenir l'adresse IP préférée en fonction de la connexion activée.
David

10
Sans connexion réseau - vous n'avez de toute façon aucune adresse IP. Par conséquent, le code reste valide, même s'il serait prudent d'ajouter un try..catch afin de gérer une telle situation et de renvoyer quelque chose comme "127.0.0.1" si une SocketException était levée.
Russ

2
@PatrickSteele, oui, il renvoie l'adresse IP sortante préférée pour la cible spécifique. si vous voulez obtenir votre adresse IP LAN, essayez d'indiquer que la cible doit être une IP de votre LAN
Mr.Wang de Next Door

2
Cette méthode fonctionne sur un mac avec un noyau dotnet, contrairement à la réponse acceptée actuellement.
Pellet

9
Cette solution fonctionne environ 4 fois plus vite que la réponse acceptée (par Mrchief). Cela devrait être la vraie réponse
Kamarey

115

Refactorisation du code de Mrcheif pour exploiter Linq (c'est-à-dire .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);
}

:)


J'ai quelques adresses IP comme "Inter Network" et cette solution fonctionne et donne la bonne. L'autre de Mrchief me donne juste le dernier. Donc en fait, celui-ci devrait être le bon;)
Keenora Fluffball

26
@KeenoraFluffball - celui-ci vous donne le premier, tandis que celui-ci vous donne le dernier (ou vice versa, dépend de la façon dont la liste est construite). Quoi qu'il en soit, ni l'un ni l'autre n'a raison - si plusieurs adresses IP vous sont données, vous devez savoir quel réseau vous utilisez. Deviner en prenant la première ou la dernière n'est pas la bonne solution.
gbjbaanb

Peut vouloir inclure également AddressFamily.InterNetworkV6
joelsand

le retour de null si le réseau n'est pas disponible n'est pas utile si vous devez également gérer des PC autonomes. Je l'ai remplacé par "return IPAddress.Loopback;" qui correspond au numéro IP spécial 127.0.0.1.
Christian

109

Je sais que cela peut donner un coup de pied à un cheval mort, mais cela peut peut-être aider quelqu'un. J'ai cherché partout un moyen de trouver mon adresse IP locale, mais partout où je trouve, il est dit d'utiliser:

Dns.GetHostEntry(Dns.GetHostName());

Je n'aime pas ça du tout parce qu'il obtient juste toutes les adresses attribuées à votre ordinateur. Si vous avez plusieurs interfaces réseau (ce que presque tous les ordinateurs font de nos jours), vous ne savez pas quelle adresse va avec quelle interface réseau. Après avoir fait un tas de recherches, j'ai créé une fonction pour utiliser la classe NetworkInterface et en extraire les informations. De cette façon, je peux dire de quel type d'interface il s'agit (Ethernet, sans fil, bouclage, tunnel, etc.), qu'elle soit active ou non, et SOOO beaucoup plus.

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 avec l'interface Ethernet.

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

ÉDITER:

Il a été souligné (merci @NasBanov) que même si cette fonction permet d'extraire l'adresse IP d'une bien meilleure manière que de l'utiliser, Dns.GetHostEntry(Dns.GetHostName())elle ne réussit pas très bien à prendre en charge plusieurs interfaces du même type ou plusieurs adresses IP sur une seule interface. . Il ne renverra une seule adresse IP que si plusieurs adresses peuvent être attribuées. Pour renvoyer TOUTES ces adresses attribuées, vous pouvez simplement manipuler la fonction d'origine pour toujours renvoyer un tableau au lieu d'une seule chaîne. 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 retournera TOUTES les adresses attribuées pour un type d'interface spécifique. Maintenant, pour obtenir une seule chaîne, vous pouvez utiliser l' .FirstOrDefault()extension pour renvoyer le premier élément du tableau ou, s'il est vide, renvoyer une chaîne vide.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();

5
C'est une meilleure solution car il n'y a pas d'utilisation DNS dans de nombreux endroits et les interfaces peuvent avoir plusieurs adresses IP. J'utilise également une méthode similaire.
Mert Gülsoy

Le problème avec cela est que vous ne renvoyez qu'une seule adresse IP par interface ... la dernière IP, pour chaque.
Nas Banov

@ compman2408 - pas vrai, une seule interface peut avoir plusieurs IP, voir en.wikipedia.org/wiki/Multihoming#Variants pour tous les combos. Un exemple évident est lors de l'exécution à la fois d'IPv4 et d'IPv6, mais dans le passé, un seul adaptateur Ethernet a participé à plusieurs réseaux IPv4. Insolite peut-être - mais parfaitement légal. Par exemple pour Windows, voir windowsnetworking.com/articles-tutorials/windows-2003/…
Nas Banov

@NasBanov Cette fonction est uniquement configurée pour obtenir des adresses IPv4, donc je ne vais même pas parler d'IPv6 et de son inutilité actuelle. Je suis conscient que le multihébergement se connecte à plusieurs réseaux sur plusieurs interfaces, mais je n'ai jamais entendu parler de la connexion à plusieurs réseaux sur la même interface. Même si vous semblez avoir raison, c'est possible, les <1% des personnes utilisant leur NIC de cette façon n'auraient qu'à changer la fonction pour retourner un tableau à la place.
compman2408

1
Merci pour ça. Pour info, au moins sur .NET 3.5 mono sur OSX item.OperationalStatusrevient toujours Unknown.
gman

36

Voici une version modifiée (de celle de compman2408) qui a fonctionné pour moi:

    internal static string GetLocalIPv4(NetworkInterfaceType _type)
    {  // Checks your IP adress from the local network connected to a gateway. This to avoid issues with double network cards
        string output = "";  // default output
        foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces()) // Iterate over each network interface
        {  // Find the network interface which has been provided in the arguments, break the loop if found
            if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
            {   // Fetch the properties of this adapter
                IPInterfaceProperties adapterProperties = item.GetIPProperties();
                // Check if the gateway adress exist, if not its most likley a virtual network or smth
                if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
                {   // Iterate over each available unicast adresses
                    foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                    {   // If the IP is a local IPv4 adress
                        if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {   // we got a match!
                            output = ip.Address.ToString();
                            break;  // break the loop!!
                        }
                    }
                }
            }
            // Check if we got a result if so break this method
            if (output != "") { break; }
        }
        // Return results
        return output;
    }

Vous pouvez appeler cette méthode par exemple comme:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

Le changement: je récupère l'IP à partir d'un adaptateur auquel une passerelle IP a été affectée. Deuxième changement: j'ai ajouté des docstrings et une instruction break pour rendre cette méthode plus efficace.


2
Solution intelligente. J'utilise maintenant cela.
RQDQ

4
A le même problème que le code dont il est dérivé: il renvoie simplement l'une des IP, une IP aléatoire parmi plusieurs - qui ne doit pas nécessairement être celle dont vous avez besoin. Il gagne le ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award
Nas Banov

1
@NasBanov, bien sûr, je l'ai gagné, comme je l'indique dans mon message: "qui a fonctionné pour moi". :-)
Gerardo H

C'est la voie à suivre, merci pour cela. Lorsque vous avez installé des commutateurs de boucle pour les émulateurs, toutes les autres variantes échouent pendant que celle-ci réussit!
DiamondDrake

1
Pourquoi ne retournez-vous que la dernière adresse IP que vous avez trouvée, pas la première? Un simpel breakdans le plus intérieur ifou un returnferait l'affaire.
Martin Mulder

20

C'est le meilleur code que j'ai trouvé pour obtenir l'adresse IP actuelle, en évitant d'obtenir l'hôte VMWare ou une autre adresse IP non valide.

public string GetLocalIpAddress()
{
    UnicastIPAddressInformation mostSuitableIp = null;

    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

    foreach (var network in networkInterfaces)
    {
        if (network.OperationalStatus != OperationalStatus.Up)
            continue;

        var properties = network.GetIPProperties();

        if (properties.GatewayAddresses.Count == 0)
            continue;

        foreach (var address in properties.UnicastAddresses)
        {
            if (address.Address.AddressFamily != AddressFamily.InterNetwork)
                continue;

            if (IPAddress.IsLoopback(address.Address))
                continue;

            if (!address.IsDnsEligible)
            {
                if (mostSuitableIp == null)
                    mostSuitableIp = address;
                continue;
            }

            // The best IP is the IP got from DHCP server
            if (address.PrefixOrigin != PrefixOrigin.Dhcp)
            {
                if (mostSuitableIp == null || !mostSuitableIp.IsDnsEligible)
                    mostSuitableIp = address;
                continue;
            }

            return address.Address.ToString();
        }
    }

    return mostSuitableIp != null 
        ? mostSuitableIp.Address.ToString()
        : "";
}

Vous devriez probablement expliquer pourquoi ce code est la solution pour la réponse. Pouvez-vous réellement obtenir une réponse à la question si vous êtes connecté à Internet et cela entraîne-t-il une erreur?
Philipp M

Les autres méthodes n'utilisent pas la validation IsDnsEligible et PrefixOrigin.
rodcesar.santos

@PhilippM Si l'adresse n'est pas éligible DNS, c'est une adresse IP interne réservée. Ce n'est pas l'hôte du fournisseur d'accès Internet. Et si PrefixOrigin a été fourni par un serveur DHCP, c'est probablement le meilleur choix d'adresse. C'est la fonction unique qui me convient!
rodcesar.santos

1
@ user1551843 - c'était super, merci. J'utilisais l'ancienne méthode GetHostByName dépréciée mais elle renvoyait l'IP d'un adaptateur VMWare :)
Jason Newland

C'était la seule solution qui fonctionnait pour moi sur vpn + wireless. Je vous remercie.
jay-danger

12

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
Ce n'est pas LINQ, ce sont des méthodes d'extension et des lambdas. Il y a une différence.
Mark

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

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

20
Mark, même sous cette forme courte, l'instruction utilise en effet LINQ-to-objects présentés avec la syntaxe de la méthode (lambda). La syntaxe de requête est simplement du sucre syntaxique qui est compilé en une chaîne d'appels de méthode d'extension IEnumerable, ce qui est LINQ-to-objects. Sources: auteur d'un fournisseur LINQ-to-SQL et d'une série d'articles sur le sujet.
constantine g


9

Pour rire, j'ai pensé essayer d'obtenir une seule instruction LINQ en utilisant le nouvel opérateur C # 6 à condition nulle. Semble assez fou et probablement horriblement inefficace, mais cela fonctionne.

private string GetLocalIPv4(NetworkInterfaceType type = NetworkInterfaceType.Ethernet)
{
    // Bastardized from: http://stackoverflow.com/a/28621250/2685650.

    return NetworkInterface
        .GetAllNetworkInterfaces()
        .FirstOrDefault(ni =>
            ni.NetworkInterfaceType == type
            && ni.OperationalStatus == OperationalStatus.Up
            && ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null
            && ni.GetIPProperties().UnicastAddresses.FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork) != null
        )
        ?.GetIPProperties()
        .UnicastAddresses
        .FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork)
        ?.Address
        ?.ToString()
        ?? string.Empty;
}

Logique gracieuseté de Gerardo H(et par référence compman2408).


Certainement amusant (+1), mais n'a en fait pas besoin d'être inefficace du tout. Me rappelle la programmation en LISP ou Forth :-)
Roland

6

Autre moyen d'obtenir IP en utilisant l'expression linq:

public static List<string> GetAllLocalIPv4(NetworkInterfaceType type)
{
    return NetworkInterface.GetAllNetworkInterfaces()
                   .Where(x => x.NetworkInterfaceType == type && x.OperationalStatus == OperationalStatus.Up)
                   .SelectMany(x => x.GetIPProperties().UnicastAddresses)
                   .Where(x => x.Address.AddressFamily == AddressFamily.InterNetwork)
                   .Select(x => x.Address.ToString())
                   .ToList();
}

5

@mrcheif J'ai trouvé cette réponse aujourd'hui et elle a été très utile même si elle a renvoyé une mauvaise adresse IP (pas à cause du code qui ne fonctionne pas) mais elle a donné la mauvaise adresse IP interréseau 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
Voulez-vous dire Logmein Hamachi? C'est une solution VPN et elle bricole la pile réseau. En outre, étant un VPN, il semble raisonnable qu'il renvoie l'IP attribuée au VPN lorsqu'il est connecté (juste ma supposition).
Mrchief

2
Complètement peu fiable. Non seulement ce n'est 192.0.0.0/8pas un test correct pour une adresse IP privée (il y a 3 plages, toutes différentes de celle-ci), il peut aussi s'agir d'une plage de réseau d'entreprise, donc pas tellement "locale".
ivan_pozdeev

5

Testé avec une ou plusieurs cartes LAN et machines virtuelles

public static string DisplayIPAddresses()
    {
        string returnAddress = String.Empty;

        // Get a list of all network interfaces (usually one per network card, dialup, and VPN connection)
        NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

        foreach (NetworkInterface network in networkInterfaces)
        {
            // Read the IP configuration for each network
            IPInterfaceProperties properties = network.GetIPProperties();

            if (network.NetworkInterfaceType == NetworkInterfaceType.Ethernet &&
                   network.OperationalStatus == OperationalStatus.Up &&
                   !network.Description.ToLower().Contains("virtual") &&
                   !network.Description.ToLower().Contains("pseudo"))
            {
                // Each network interface may have multiple IP addresses
                foreach (IPAddressInformation address in properties.UnicastAddresses)
                {
                    // We're only interested in IPv4 addresses for now
                    if (address.Address.AddressFamily != AddressFamily.InterNetwork)
                        continue;

                    // Ignore loopback addresses (e.g., 127.0.0.1)
                    if (IPAddress.IsLoopback(address.Address))
                        continue;

                    returnAddress = address.Address.ToString();
                    Console.WriteLine(address.Address.ToString() + " (" + network.Name + " - " + network.Description + ")");
                }
            }
        }

       return returnAddress;
    }

Gardez à l'esprit que celui-ci fonctionne uniquement pour Ethernet. Supprimez la restriction NetworkInterfaceType pour prendre en charge le Wi-Fi.
scor4er

3

Juste une version mise à jour de la mienne utilisant LINQ:

/// <summary>
/// Gets the local Ipv4.
/// </summary>
/// <returns>The local Ipv4.</returns>
/// <param name="networkInterfaceType">Network interface type.</param>
IPAddress GetLocalIPv4(NetworkInterfaceType networkInterfaceType)
{
    var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces().Where(i => i.NetworkInterfaceType == networkInterfaceType && i.OperationalStatus == OperationalStatus.Up);

    foreach (var networkInterface in networkInterfaces)
    {
        var adapterProperties = networkInterface.GetIPProperties();

        if (adapterProperties.GatewayAddresses.FirstOrDefault() == null)
                continue;
        foreach (var ip in networkInterface.GetIPProperties().UnicastAddresses)
        {
            if (ip.Address.AddressFamily != AddressFamily.InterNetwork)
                    continue;

            return ip.Address;
        }
    }

    return null;
}

2

Pré-requis: vous devez ajouter la référence System.Data.Linq et la référencer

using System.Linq;
string ipAddress ="";
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
ipAddress = Convert.ToString(ipHostInfo.AddressList.FirstOrDefault(address => address.AddressFamily == AddressFamily.InterNetwork));

2

J'avais également du mal à obtenir la bonne adresse IP.

J'ai essayé une variété de solutions ici, mais aucune ne m'a fourni l'effet souhaité. Presque tous les tests conditionnels fournis n’ont pas permis d’utiliser d’adresse.

C'est ce qui a fonctionné pour moi, j'espère que cela aide ...

var firstAddress = (from address in NetworkInterface.GetAllNetworkInterfaces().Select(x => x.GetIPProperties()).SelectMany(x => x.UnicastAddresses).Select(x => x.Address)
                    where !IPAddress.IsLoopback(address) && address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork
                    select address).FirstOrDefault();

Console.WriteLine(firstAddress);

1
string str="";

System.Net.Dns.GetHostName();

IPHostEntry ipEntry = System.Net.Dns.GetHostEntry(str);

IPAddress[] addr = ipEntry.AddressList;

string IP="Your Ip Address Is :->"+ addr[addr.Length - 1].ToString();

str est toujours vide
aj.toulan

1

Gardez à l'esprit que, dans le cas général, vous pouvez avoir plusieurs traductions NAT en cours et plusieurs serveurs DNS, chacun fonctionnant sur des niveaux de traduction NAT différents.

Que faire si vous avez un NAT de classe opérateur et que vous souhaitez communiquer avec d'autres clients du même opérateur? Dans le cas général, vous ne savez jamais avec certitude car vous pouvez apparaître avec des noms d'hôtes différents à chaque traduction NAT.


1

Obsolète disparu, cela fonctionne pour moi

public static IPAddress GetIPAddress()
{ 
 IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
 address.AddressFamily == AddressFamily.InterNetwork).First();
 return ip;
}

1

En mettant à jour la réponse de Mrchief avec Linq, nous aurons:

public static IPAddress GetLocalIPAddress()
{
   var host = Dns.GetHostEntry(Dns.GetHostName());
   var ipAddress= host.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork);
   return ipAddress;
}

1

Cela renvoie les adresses de toutes les interfaces qui ont des adresses de passerelle et des adresses de monodiffusion dans deux listes distinctes, IPV4 et IPV6.

public static (List<IPAddress> V4, List<IPAddress> V6) GetLocal()
{
    List<IPAddress> foundV4 = new List<IPAddress>();
    List<IPAddress> foundV6 = new List<IPAddress>();

    NetworkInterface.GetAllNetworkInterfaces().ToList().ForEach(ni =>
    {
        if (ni.GetIPProperties().GatewayAddresses.FirstOrDefault() != null)
        {
            ni.GetIPProperties().UnicastAddresses.ToList().ForEach(ua =>
            {
                if (ua.Address.AddressFamily == AddressFamily.InterNetwork) foundV4.Add(ua.Address);
                if (ua.Address.AddressFamily == AddressFamily.InterNetworkV6) foundV6.Add(ua.Address);
            });
        }
    });

    return (foundV4.Distinct().ToList(), foundV6.Distinct().ToList());
}

Solution soignée :)
Johan Franzén

1

Il y a déjà beaucoup de réponses, mais j'apporte toujours la mienne:

public static IPAddress LocalIpAddress() {
    Func<IPAddress, bool> localIpPredicate = ip =>
        ip.AddressFamily == AddressFamily.InterNetwork &&
        ip.ToString().StartsWith("192.168"); //check only for 16-bit block
    return Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(localIpPredicate);
}

Bon mot:

public static IPAddress LocalIpAddress() => Dns.GetHostEntry(Dns.GetHostName()).AddressList.LastOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork && ip.ToString().StartsWith("192.168"));

Remarque: recherchez à partir du dernier car cela fonctionnait toujours après l'ajout de certaines interfaces dans l'appareil, telles que MobileHotspot, VPN ou autres adaptateurs virtuels fantaisistes.


1
Donc, si mon adresse IP locale est 10.0.2.3, elle n'est pas trouvée? C'est vraiment bizarre dans ce code.
frankhommers

@frankhommers a été dit vérifier uniquement pour le bloc 16 bits
nyconing

Les blocs 16 bits peuvent également être autre chose que 192.168
frankhommers

0

De plus, un code simple pour obtenir Client Ip:

        public static string getclientIP()
        {
            var HostIP = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "";
            return HostIP;
        }

J'espère que cela vous aidera.


0
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1].MapToIPv4() //returns 192.168.14.1

entrez la description de l'image ici


5
Votre réponse devrait contenir une description de la façon dont cela fonctionne pour le cas de l'OP et également pour les futurs lecteurs.
Ronak Dhoot

Il est préférable d'inclure une explication de votre réponse pour les futurs lecteurs.
Nicolas Gervais

0

Code de compman2408 modifié pour pouvoir parcourir chacun d'eux NetworkInterfaceType.

public static string GetLocalIPv4 (NetworkInterfaceType _type) {
    string output = null;
    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;
}

Et vous pouvez l'appeler ainsi:

static void Main (string[] args) {
    // Get all possible enum values:
    var nitVals = Enum.GetValues (typeof (NetworkInterfaceType)).Cast<NetworkInterfaceType> ();

    foreach (var nitVal in nitVals) {
        Console.WriteLine ($"{nitVal} => {GetLocalIPv4 (nitVal) ?? "NULL"}");
    }
}

0
Imports System.Net
Imports System.Net.Sockets
Function LocalIP()
    Dim strHostName = Dns.GetHostName
    Dim Host = Dns.GetHostEntry(strHostName)
    For Each ip In Host.AddressList
        If ip.AddressFamily = AddressFamily.InterNetwork Then
            txtIP.Text = ip.ToString
        End If
    Next

    Return True
End Function

En dessous de la même action

Fonction LocalIP ()

Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString

txtIP.Text = Hôte

Retour vrai

Fonction de fin


L'exemple ci-dessous est la même action Function LocalIP () Dim Host As String = Dns.GetHostEntry (Dns.GetHostName) .AddressList (1) .MapToIPv4.ToString txtIP.Text = Host Return True End Function
YongJae Kim

-2
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1]

une ligne de code: D


7
Il peut lever une OutOfRangeException dans certains cas.
Loudenvier

5
Aussi, comment savez-vous lequel vous voulez? Ce qui est bon pour vous pourrait être mauvais pour quelqu'un d'autre.
Mark

-3

Si vous avez des machines virtuelles ou des cartes réseau supplémentaires, il peut y avoir d'autres valeurs dans la liste d'adresses. Ma suggestion est de vérifier les entrées de la liste d'adresses et d'imprimer ce qui est approprié. Dans mon cas, l'entrée 3 était l'adresse IPv4 de ma machine

IPHostEntry ipHost = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddr = ipHost.AddressList[3];
string ip = ipAddr.ToString();

N'oubliez pas d'ajouter using System.Net;


1
Correction; Tous sont l'adresse IP de votre machine. Laquelle vous voulez, cependant, est une toute autre histoire. Notez que l'ordre peut changer et qu'en raison de la méthode que vous utilisez, vous allez toujours deviner.
Mark

C'est ce que j'ai dit, vous devriez vérifier les entrées de la liste d'adresses, et oui, c'est deviner, mais après avoir vu toutes les entrées, deviner n'est pas très difficile
Bibaswann Bandyopadhyay

Comment sauriez-vous ce qui est approprié? En utilisant la solution de compman2048, vous sauriez au moins laquelle est liée à quelle interface.
Mark

Cette solution n'a pas fonctionné sur mon ordinateur, car j'ai 2 interfaces WLAN, 2 machines virtuelles et 1 émulateur, donc j'ai eu beaucoup d'adresses IP. Mais si vous recherchez une adresse interne fournie par le routeur, elle commencera par 192 ou 172 ou 10, c'est comme ça que j'ai compris
Bibaswann Bandyopadhyay

À moins que votre routeur ne distribue des adresses IP publiques, ce qui est rare mais possible.
Mark
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.