web-dev-qa-db-fra.com

Obtenir l'adresse IP locale

Sur Internet, plusieurs endroits 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, je reçois plusieurs adresses IP, mais je ne souhaite obtenir que celle attribuée par le routeur à l’ordinateur exécutant le programme: l’adresse IP que j’aimerais donner à une personne qui souhaite accéder à un dossier partagé de mon ordinateur pendant une période donnée. exemple.

Si je ne suis pas connecté à un réseau et que je suis connecté à 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 si c'est ensuite pour obtenir l'adresse IP du réseau local.

252
Tono Nam

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

411
Mrchief

Il existe un moyen plus précis lorsque plusieurs adresses IP sont disponibles sur la machine locale. Connect un socket UDP et lit son noeud final 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, élimine tous les paquets d'autres adresses et, ce que nous utilisons, transfère le socket dans état "connecté", paramétrant ses champs appropriés. Cela inclut la vérification de l'existence de la route vers la destination en fonction de la table de routage du système et la définition du noeud final local en conséquence. La dernière partie semble être officiellement non documentée, mais elle ressemble à un trait intégral de API de sockets Berkeley (un effet secondaire de l'état "connecté" d'UDP) qui fonctionne de manière fiable à la fois sous Windows et Linux à travers les versions et les distributions.

Donc, cette méthode donnera l'adresse locale qui serait utilisée pour se connecter à l'hôte distant spécifié. Aucune connexion réelle n'étant établie, l'adresse IP distante spécifiée peut être inaccessible.

185

Refactoriser le code de Mrcheif pour tirer parti de 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);
}

:)

104
Pure.Krome

Je sais que cela peut être un coup de pied contre 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 je trouve qu'il est dit d'utiliser:

Dns.GetHostEntry(Dns.GetHostName());

Je n'aime pas du tout cela car il ne contient que toutes les adresses attribuées à votre ordinateur. Si vous avez plusieurs interfaces réseau (ce que presque tous les ordinateurs ont maintenant), vous ne savez pas quelle adresse correspond à quelle interface réseau. Après avoir effectué de nombreuses recherches, j'ai créé une fonction permettant d'utiliser la classe NetworkInterface et d'extraire les informations de celle-ci. De cette façon, je peux savoir de quel type d’interface il s’agit (Ethernet, sans fil, en boucle, tunnel, etc.), s’il est actif ou non, et bien plus 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 qu'une carte sans fil n'est pas installée sur votre ordinateur, elle renverra simplement une chaîne vide. Même chose avec l'interface Ethernet.

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

EDIT:

Il a été souligné (merci @NasBanov) que, même si cette fonction permet d'extraire l'adresse IP d'une manière bien meilleure que d'utiliser Dns.GetHostEntry(Dns.GetHostName()), elle ne supporte pas très bien plusieurs interfaces du même type ou plusieurs adresses IP sur un même ordinateur. interface. Il ne renvoie qu'une seule adresse IP lorsque 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 renverra TOUTES les adresses attribuées pour un type d'interface spécifique. Maintenant, pour obtenir une seule chaîne, vous pouvez utiliser l'extension .FirstOrDefault() pour renvoyer le premier élément du tableau ou, s'il est vide, renvoyer une chaîne vide.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
93
compman2408

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

internal static string GetLocalIPv4(NetworkInterfaceType _type)
{
    string output = "";
    foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
    {
        if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
        {
            IPInterfaceProperties adapterProperties = item.GetIPProperties();

            if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
            {
                foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses)
                {
                    if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        output = ip.Address.ToString();
                    }
                }
            }
        }
    }

    return output;
}

Le changement: je récupère l'adresse IP d'un adaptateur auquel une adresse IP de passerelle lui est attribuée.

25
Gerardo H

C'est le meilleur code que j'ai trouvé pour obtenir l'adresse IP actuelle, en évitant d'obtenir un 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()
        : "";
}
18
rodcesar.santos

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()
10
Kapé

Pour rire, j'ai pensé que j'essaierais d'obtenir une seule instruction LINQ en utilisant le nouvel opérateur C-6 null-conditionnel. Ça a l'air assez fou et probablement horriblement inefficace, mais ça marche.

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 fournie par Gerardo H (et par référence compman2408).

6
Stajs

@mrcheif J'ai trouvé cette réponse aujourd'hui et elle était très utile bien qu'elle renvoie une mauvaise adresse IP (car le code ne fonctionne pas), mais une mauvaise adresse IP interréseau existe lorsque vous exécutez des tâches telles que Himachi.

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;
}
4
Jordan Trainor

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

Autre moyen d'obtenir une adresse IP à l'aide de 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();
}
3
Amirhossein Yari

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

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

Juste une version mise à jour du mien en 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;
}
1
Giusepe

J'avais également du mal à obtenir l'adresse IP correcte.

J'ai essayé une variété de solutions ici mais aucune ne m'a fourni l'effet désiré. La quasi-totalité des tests conditionnels fournis ne nécessitait aucune adresse.

C'est ce qui a fonctionné pour moi, espérons 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
UberBiza

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
Ashkan Sirous

Gardez à l'esprit que, dans le cas général, plusieurs traductions NAT sont en cours, ainsi que plusieurs serveurs DNS, chacun opérant sur différents niveaux de traduction NAT.

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

1
sgjsfth sthseth

Obsolète parti, cela fonctionne pour moi

public static IPAddress GetIPAddress()
{ 
 IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address => 
 address.AddressFamily == AddressFamily.InterNetwork).First();
 return ip;
}
1
Sourcephy
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();
1
Naimish Mungara

De plus, un simple code pour obtenir un client IP:

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

J'espère que ça vous aidera.

0
Majedur Rahaman