Ottieni l'indirizzo IP locale


301

In Internet ci sono diversi posti che mostrano come ottenere un indirizzo IP. E molti di loro assomigliano a questo esempio:

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

Con questo esempio ottengo diversi indirizzi IP, ma sono interessato solo a ottenere quello che il router assegna al computer che esegue il programma: l'IP che darei a qualcuno se desidera accedere a una cartella condivisa nel mio computer per esempio.

Se non sono connesso a una rete e sono connesso a Internet direttamente tramite un modem senza router, vorrei ricevere un errore. Come posso vedere se il mio computer è collegato a una rete con C # e se è quindi per ottenere l'indirizzo IP LAN.


If I am not connected to a network and I am connected to the internet Questa affermazione sembra contraddittoria. Stai cercando di capire se il tuo computer è connesso a una LAN privata o a Internet?
Andy,

4
Proprio come un avvertimento: un computer può avere più di un'interfaccia IP, ad esempio una LAN e WiFi. Se si associa un servizio a un particolare componente hardware (ad esempio la LAN), è necessario l'IP della LAN. La maggior parte dei seguenti esempi restituirà il "primo" o "ultimo" indirizzo IP trovato. Se hai più di 2 indirizzi IP, il tuo programma potrebbe funzionare il 50% delle volte, a seconda dell'ordine casuale in cui il sistema operativo restituisce gli indirizzi IP.
Mark Lakata,

@MarkLakata Ho pensato allo stesso problema. La funzione nella mia risposta di seguito lo gestirà. È possibile specificare da quale tipo di interfaccia di rete si desidera l'indirizzo IP.
compman2408,

3
Solo FTR, se vai su Google per Unity3D, è Network.player.ipIndirizzo nella loro API
Fattie

@MarkLakata in senso stretto, il "primo" o "ultimo" IP è l' IP "corretto", poiché il browser può utilizzare qualsiasi IP disponibile. Probabilmente una buona correzione dovrebbe essere quella di restituire ogni IP associato alla macchina.
UncaAlby,

Risposte:


457

Per ottenere l'indirizzo 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!");
}

Per verificare se sei connesso o meno:

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


29
non funzionerà se usi cose come vm virtual box, genymotion, ecc.
PauLEffect,

5
Concordo con PaulEffect. Non solo questo metodo è dannoso per più schede di rete, ma non distingue tra indirizzi IP v6 e indirizzi IP v4.
Max

16
@John AddressFamily.InterNetwork è IP v4 e AddressFamily.InterNetworkV6 è IP v6
Leonardo Xavier,

Sto usando Geraldo H Answer, ma se qualcuno lo sta usando, potresti voler rimuovere tutti gli ips che terminano con 1, quindi rimuoverà iback di loopback e virtualbox / vmware
Leonardo Xavier,

6
Sembra che tu stia utilizzando VMWare o altri software di virtualizzazione. L'OP non lo ha chiesto, quindi penso che votare in basso a causa di ciò sia un po 'duro. Se si dispone di VMWare o di più schede di rete, alcune delle altre risposte forniscono già degli indizi.
Mrchief,

218

Esiste un modo più accurato quando sono disponibili indirizzi IP multipli sul computer locale. Connectun socket UDP e leggere il suo endpoint locale:

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

Connectsu un socket UDP ha il seguente effetto: imposta la destinazione per Send/ Recv, scarta tutti i pacchetti da altri indirizzi e - che è quello che usiamo - trasferisce il socket nello stato "connesso", imposta i campi appropriati. Ciò include la verifica dell'esistenza del percorso verso la destinazione in base alla tabella di routing del sistema e l'impostazione dell'endpoint locale di conseguenza. L'ultima parte sembra non essere documentata ufficialmente ma sembra un tratto integrale dell'API socket Berkeley (un effetto collaterale dello stato "connesso" UDP) che funziona in modo affidabile sia su Windows che su Linux attraverso versioni e distribuzioni.

Quindi, questo metodo fornirà l'indirizzo locale che verrebbe utilizzato per connettersi all'host remoto specificato. Non è stata stabilita alcuna connessione reale, quindi l'ip remoto specificato può essere irraggiungibile.


4
Questa è la migliore soluzione che ha funzionato per le mie esigenze. Nella mia situazione ho molte schede di rete e alcune connessioni wireless. Avevo bisogno di ottenere l'indirizzo IP preferito in base alla connessione attivata.
David

10
Senza una connessione di rete - comunque non hai un indirizzo IP. Pertanto, il codice è ancora valido, anche se sarebbe prudente aggiungere un tentativo..catch per gestire una situazione del genere e restituire qualcosa come "127.0.0.1" se viene generata una SocketException.
Russ,

2
@PatrickSteele, sì, restituisce l'indirizzo IP in uscita preferito per la destinazione specifica. se vuoi ottenere il tuo indirizzo IP LAN, prova a indicare che l'obiettivo è un IP dalla tua LAN
Mr.Wang di Next Door,

2
Questo metodo funziona su un Mac con dotnet core, mentre attualmente la risposta accettata no.
Pellet

9
Questa soluzione funziona circa 4 volte più velocemente della risposta accettata (da Mrchief). Questa dovrebbe essere la vera risposta
Kamarey,

115

Rifattorizzare il codice di Mrcheif per sfruttare Linq (es. .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);
}

:)


Ho alcuni indirizzi IP come "Inter Network" e questa soluzione funziona davvero e restituisce quella giusta. L'altro di Mrchief mi dà solo l'ultimo. Quindi in realtà questo dovrebbe essere quello giusto;)
Keenora Fluffball

26
@KeenoraFluffball - questo ti dà il primo, mentre questo ti dà l'ultimo (o viceversa, dipende da come è costruito l'elenco). In entrambi i casi, nessuno dei due ha ragione: se ci sono più di 1 indirizzo IP che ti viene dato, devi sapere quale rete stai usando. Indovinare prendendo il primo o l'ultimo non è la soluzione corretta.
gbjbaanb,

Potrebbe voler includere anche AddressFamily.InterNetworkV6
joelsand

il ritorno di null se la rete non è disponibile non è utile se si devono gestire anche PC standalone. L'ho sostituito con "return IPAddress.Loopback;" che corrisponde al numero IP speciale 127.0.0.1.
Christian,

109

So che questo potrebbe dare dei calci a un cavallo morto, ma forse questo può aiutare qualcuno. Ho cercato dappertutto un modo per trovare il mio indirizzo IP locale, ma ovunque trovo che dice di usare:

Dns.GetHostEntry(Dns.GetHostName());

Non mi piace affatto perché ottiene tutti gli indirizzi assegnati al tuo computer. Se si dispone di più interfacce di rete (che praticamente tutti i computer fanno ora al giorno) non si ha idea di quale indirizzo corrisponda a quale interfaccia di rete. Dopo aver fatto un sacco di ricerche, ho creato una funzione per utilizzare la classe NetworkInterface e strapparne le informazioni. In questo modo posso dire che tipo di interfaccia è (Ethernet, wireless, loopback, tunnel, ecc.), Se è attiva o meno e SOOO molto di più.

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

Ora per ottenere l'indirizzo IPv4 della chiamata dell'interfaccia di rete Ethernet:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

O la tua interfaccia wireless:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Se si tenta di ottenere un indirizzo IPv4 per un'interfaccia wireless, ma sul computer non è installata una scheda wireless, verrà restituita una stringa vuota. Stessa cosa con l'interfaccia Ethernet.

Spero che questo aiuti qualcuno! :-)

MODIFICARE:

È stato sottolineato (grazie a @NasBanov) che anche se questa funzione consente di estrarre l'indirizzo IP in un modo molto migliore rispetto all'utilizzo Dns.GetHostEntry(Dns.GetHostName())non funziona molto bene nel supportare più interfacce dello stesso tipo o più indirizzi IP su una singola interfaccia . Restituirà un solo indirizzo IP quando potrebbero essere assegnati più indirizzi. Per restituire TUTTI questi indirizzi assegnati, è possibile semplicemente manipolare la funzione originale per restituire sempre un array anziché una singola stringa. Per esempio:

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

Ora questa funzione restituirà TUTTI gli indirizzi assegnati per uno specifico tipo di interfaccia. Ora per ottenere una sola stringa, è possibile utilizzare l' .FirstOrDefault()estensione per restituire il primo elemento dell'array o, se è vuoto, restituire una stringa vuota.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();

5
Questa è una soluzione migliore perché non c'è usabilità del DNS in molti luoghi e le interfacce possono avere più indirizzi IP. Uso anche un metodo simile.
Mert Gülsoy,

Il problema con questo è che si restituisce solo 1 indirizzo IP per interfaccia ... l'ultimo IP, foreach.
Nas Banov,

@ compman2408 - non è vero, una singola interfaccia può avere più IP, vedi en.wikipedia.org/wiki/Multihoming#Variants per tutte le combo. Un esempio evidente è quando eseguo sia IPv4 che IPv6, ma in passato ho avuto un singolo adattatore ethernet che partecipava a più reti IPv4. Insolito forse - eppure perfettamente legale. Ad esempio, per Windows vedere windowsnetworking.com/articles-tutorials/windows-2003/…
Nas Banov

@NasBanov Questa funzione è impostata solo per ottenere indirizzi IPv4, quindi non parlerò nemmeno di IPv6 e della sua attuale inutilità. Sono a conoscenza del multihoming come connessione a più reti su più interfacce, tuttavia non ho mai sentito parlare di connessione a più reti sulla stessa interfaccia. Anche se sembra che tu abbia ragione a dire che è effettivamente possibile, <1% delle persone che usano la loro scheda NIC in questo modo dovrebbe semplicemente cambiare la funzione per restituire un array.
compman2408

1
Grazie per questo. Cordiali saluti, almeno su .NET 3.5 mono su OSX item.OperationalStatusritorna sempre Unknown.
Gman,

36

Ecco una versione modificata (da quella di compman2408) che ha funzionato per me:

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

Puoi chiamare questo metodo per esempio come:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

La modifica: sto recuperando l'IP da un adattatore a cui è assegnato un IP gateway. Seconda modifica: ho aggiunto docstring e break statement per rendere questo metodo più efficiente.


2
Soluzione intelligente. Ora sto usando questo.
RQDQ

4
Ha lo stesso problema del codice da cui è derivato: restituisce solo uno degli IP, un IP casuale da molti - che non deve essere quello di cui hai bisogno. Guadagna l' ademiller.com
Nas Banov

1
@NasBanov, certo che me lo sono guadagnato, come sto affermando nel mio post: "che ha funzionato per me". :-)
Gerardo H,

Questa è la strada da percorrere, grazie per questo. Quando sono installati interruttori di loopback per emulatori, tutte le altre varianti falliscono mentre questa ha esito positivo!
DiamondDrake,

1
Perché restituisci solo l'ultimo indirizzo IP che hai trovato, non il primo? Un simpel breaknel più interiore ifo un returnfarebbe il trucco.
Martin Mulder,

20

Questo è il miglior codice che ho trovato per ottenere l'IP corrente, evitando di ottenere host VMWare o altri indirizzi IP non validi.

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

Probabilmente dovresti spiegare perché questo codice è la soluzione per la risposta. Puoi effettivamente ottenere una risposta alla domanda se sei connesso a Internet e questo provoca un errore?
Philipp M,

Gli altri modi non utilizzano la convalida IsDnsEligible e PrefixOrigin.
rodcesar.santos,

@PhilippM Se l'indirizzo non è un DNS idoneo, è un IP interno riservato. Non è l'host del provider Internet. E se PrefixOrigin è stato fornito da un server DHCP, questa è la scelta migliore per l'indirizzo. Questa è la funzione unica che funziona per me!
rodcesar.santos,

1
@utente1551843 - è stato fantastico, grazie. Stavo usando il vecchio metodo GetHostByName deprezzato ma restituiva l'IP di un adattatore VMWare :)
Jason Newland,

Questa è stata l'unica soluzione che ha funzionato per me su VPN + wireless. Grazie.
jay-danger

12

Penso che usare LinQ sia più semplice:

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

14
Questo non è LINQ, sono metodi di estensione e lambda. C'è una differenza
Segna il

10
@Mark - Se non aggiungi "using System.Linq;" non è possibile utilizzare il metodo di estensione "First"
BornToCode

5
Questo perché il metodo di estensione si trova nella classe Enumerable che si trova nello spazio dei nomi System.Linq. Non è ancora LINQ.
Segna l'

20
Mark, anche in questa breve forma, l'istruzione sta effettivamente usando LINQ-to-objects presentato con la sintassi del metodo (lambda). La sintassi della query è semplicemente zucchero sintattico che viene compilato in una catena di chiamate al metodo di estensione IEnumerable, che è ciò che è LINQ-to-object. Fonti: autore di un provider LINQ-to-SQL e una serie di articoli sull'argomento.
Costantino g


9

Per una risata, ho pensato di provare a ottenere una singola istruzione LINQ utilizzando il nuovo operatore null # C # 6. Sembra piuttosto pazzo e probabilmente terribilmente inefficiente, ma funziona.

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

Logica per gentile concessione di Gerardo H(e per riferimento compman2408).


Decisamente divertente (+1), ma in realtà non deve essere affatto inefficiente. Mi ricorda la programmazione in LISP o Forth :-)
Roland

6

Altro modo per ottenere IP usando l'espressione 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 Ho trovato questa risposta oggi ed è stato molto utile anche se ha restituito un IP errato (non dovuto al codice non funzionante) ma ha dato un IP internetwork errato quando hai cose come Himachi in esecuzione.

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
Intendi Logmein Hamachi? È una soluzione VPN e armeggia con lo stack di rete. Inoltre, essendo una VPN, sembra ragionevole che restituisca l'IP assegnato alla VPN quando connesso (solo la mia ipotesi).
Mrchief,

2
Completamente inaffidabile. Non solo 192.0.0.0/8non è un test corretto per un indirizzo IP privato (ci sono 3 intervalli, tutti diversi da questo), può anche essere un intervallo di rete aziendale, quindi non tanto "locale".
ivan_pozdeev,

5

Testato con una o più schede LAN e macchine virtuali

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

Tieni presente che questo funziona solo per Ethernet. Rimuovi la limitazione NetworkInterfaceType per supportare la connessione wi-fi.
scor4er,

3

Solo una mia versione aggiornata usando 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

Prerequisiti: è necessario aggiungere il riferimento System.Data.Linq e consultarlo

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

2

Stavo anche lottando per ottenere l'IP corretto.

Ho provato una varietà di soluzioni qui, ma nessuna mi ha fornito l'effetto desiderato. Quasi tutti i test condizionali forniti non hanno consentito di utilizzare alcun indirizzo.

Questo è ciò che ha funzionato per me, spero che aiuti ...

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 è sempre vuoto
aj.toulan,

1

Tieni presente che, in generale, potresti avere più traduzioni NAT in corso e più server DNS, ognuno operante su diversi livelli di traduzione NAT.

Cosa succede se si dispone di NAT di livello carrier e si desidera comunicare con altri clienti dello stesso vettore? Nel caso generale non lo saprai mai perché potresti apparire con nomi host diversi in ogni traduzione NAT.


1

Obsoleto andato, questo funziona per me

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

1

Aggiornando la risposta di Mrchief con Linq, avremo:

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

1

Ciò restituisce gli indirizzi da tutte le interfacce che hanno indirizzi gateway e indirizzi unicast in due elenchi separati, IPV4 e 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());
}

Soluzione ordinata :)
Johan Franzén,

1

Ci sono già molte risposte, ma sto ancora contribuendo alla mia:

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

Una fodera:

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

nota: cerca dall'ultimo perché ha funzionato ancora dopo che alcune interfacce sono state aggiunte al dispositivo, come MobileHotspot, VPN o altri adattatori virtuali fantasiosi.


1
Quindi se il mio IP locale è 10.0.2.3 non viene trovato? È davvero strano in questo codice.
Frankhommers,

A @frankhommers è stato detto di controllare solo per il blocco a 16 bit
nyconing

I blocchi a 16 bit possono anche essere qualcosa di diverso da 192.168
frankhommers

0

Inoltre, basta un semplice codice per ottenere l'IP del cliente:

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

Spero ti sia d'aiuto.


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

inserisci qui la descrizione dell'immagine


5
La tua risposta dovrebbe contenere una descrizione di come funziona per il caso di OP e anche per i lettori futuri.
Ronak Dhoot l'

È meglio includere una spiegazione della tua risposta per i futuri lettori.
Nicolas Gervais,

0

Codice di compman2408 modificato per poter iterare su ciascuno di essi 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;
}

E puoi chiamarlo così:

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

Sotto la stessa azione

Funzione LocalIP ()

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

txtIP.Text = Host

Return True

Fine funzione


L'esempio sotto è la stessa azione Funzione 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]

una riga di codice: D


7
In alcuni casi potrebbe generare una OutOfRangeException.
Loudenvier,

5
Inoltre, come fai a sapere quale vuoi? Ciò che è giusto per te potrebbe essere sbagliato per qualcun altro.
Segna il

-3

Se si dispone di macchine virtuali o schede di rete aggiuntive, potrebbero essere presenti altri valori nell'elenco indirizzi. Il mio suggerimento è di controllare le voci dell'elenco indirizzi e di stampare ciò che è appropriato. Nel mio caso la voce 3 era l'indirizzo ipv4 della mia macchina

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

Non dimenticare di aggiungere using System.Net;


1
Correzione; TUTTI sono l'indirizzo IP della tua macchina. Quella che vuoi, tuttavia, è tutta un'altra storia. Nota che l'ordine può cambiare e, a causa del metodo che stai utilizzando, indovinerai sempre.
Segna il

Questo è quello che ho detto, dovresti controllare le voci dell'elenco indirizzi, e sì è indovinare, ma dopo aver visto tutte le voci, indovinare non è molto difficile
Bibaswann Bandyopadhyay

Come faresti a sapere quale è appropriato? Usando la soluzione di compman2048, almeno sapresti quale è legato a quale interfaccia.
Segna il

Quella soluzione non ha funzionato sul mio computer, perché ho 2 interfacce wlan, 2 macchine virtuali e 1 emulatore, quindi ho ottenuto molti IP. Ma se stai cercando l'indirizzo interno fornito dal router, inizierà con 192 o 172 o 10, è così che ho capito
Bibaswann Bandyopadhyay

A meno che il router non distribuisca IP pubblici, il che è raro ma possibile.
Segna il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.