Obtener dirección IP local

301

En Internet hay varios lugares que le muestran cómo obtener una dirección IP. Y muchos de ellos se parecen a este ejemplo:

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 este ejemplo, obtengo varias direcciones IP, pero solo estoy interesado en obtener la que el enrutador asigna a la computadora que ejecuta el programa: la IP que le daría a alguien si desea acceder a una carpeta compartida en mi computadora para ejemplo.

Si no estoy conectado a una red y estoy conectado a Internet directamente a través de un módem sin enrutador, me gustaría recibir un error. ¿Cómo puedo ver si mi computadora está conectada a una red con C # y si es para obtener la dirección IP de LAN?

Tono Nam
fuente
If I am not connected to a network and I am connected to the internet Esta afirmación parece contradictoria. ¿Estás tratando de averiguar si tu computadora está conectada a una LAN privada o a Internet?
Andy
44
Solo como advertencia: una computadora puede tener más de una interfaz IP, por ejemplo, una LAN y WiFi. Si vincula un servicio a una pieza de hardware en particular (por ejemplo, la LAN), necesita la IP de la LAN. La mayoría de los siguientes ejemplos devolverán la "primera" o "última" dirección IP encontrada. Si tiene más de 2 direcciones IP, su programa puede funcionar el 50% del tiempo, dependiendo del orden aleatorio que el SO devuelve las direcciones IP.
Mark Lakata
@ MarkLakata Pensé en el mismo problema. La función en mi respuesta a continuación lo manejará. Puede especificar de qué tipo de interfaz de red desea la dirección IP.
compman2408
3
Solo FTR, si buscas en Google aquí para Unity3D, es Network.player.ipAddress en su API
Fattie
@MarkLakata estrictamente hablando, la "primera" o "última" IP es la IP "correcta", ya que el navegador puede usar cualquier IP que esté disponible. Probablemente una buena corrección debería ser devolver cada IP asociada con la máquina.
UncaAlby

Respuestas:

457

Para obtener la dirección IP local:

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

Para verificar si estás conectado o no:

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

Mrchief
fuente
29
no funcionará si usa cosas como vm virtual box, genymotion, etc.
PauLEffect el
55
De acuerdo con PaulEffect. No solo este método es malo para múltiples tarjetas de red, sino que tampoco diferencia entre las direcciones IP v6 e IP v4.
Max
16
@John AddressFamily.InterNetwork es IP v4 y AddressFamily.InterNetworkV6 es IP v6
Leonardo Xavier
Estoy usando Geraldo H Answer, pero si alguien está usando esto, es posible que desee eliminar todos los ips que terminan con 1, por lo que eliminará el loopback y los ips predeterminados de virtualbox / vmware
Leonardo Xavier
66
Parece que está utilizando VMWare u otro software de virtualización. El OP no pidió eso, así que creo que rechazar la votación debido a eso es un poco duro. Si tiene VMWare o varias NIC, algunas de las otras respuestas ya proporcionan pistas sobre eso.
Mrchief
218

Hay una forma más precisa cuando hay direcciones IP múltiples disponibles en la máquina local. Connectun socket UDP y lee su punto 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();
}

Connecten un socket UDP tiene el siguiente efecto: establece el destino para Send/ Recv, descarta todos los paquetes de otras direcciones y, que es lo que usamos, transfiere el socket al estado "conectado", configura sus campos apropiados. Esto incluye verificar la existencia de la ruta hacia el destino de acuerdo con la tabla de enrutamiento del sistema y establecer el punto final local en consecuencia. La última parte parece no estar documentada oficialmente, pero parece un rasgo integral de la API de sockets de Berkeley (un efecto secundario del estado UDP "conectado") que funciona de manera confiable tanto en Windows como en Linux en todas las versiones y distribuciones.

Por lo tanto, este método proporcionará la dirección local que se usaría para conectarse al host remoto especificado. No hay una conexión real establecida, por lo tanto, la IP remota especificada puede ser inalcanzable.

Mr.Wang de al lado
fuente
44
Esta es la mejor solución que funcionó para mis necesidades. En mi situación, tengo muchas tarjetas de red y algunas conexiones inalámbricas. Necesitaba obtener la dirección IP preferida según la conexión que se activó.
David
10
Sin una conexión de red, de todos modos no tiene una dirección IP. Por lo tanto, el código sigue siendo válido, aunque sería prudente agregar un try..catch para manejar tal situación y devolver algo como "127.0.0.1" si se lanzara una SocketException.
Russ
2
@PatrickSteele, sí, devuelve la dirección IP de salida preferida para el objetivo específico. si desea obtener su dirección IP de LAN, intente indicar que el objetivo debe ser alguna ip de su LAN
Mr.Wang de Next Door
2
Este método funciona en una mac con dotnet core, mientras que la respuesta aceptada actualmente no.
Pellet
99
Esta solución funciona aproximadamente 4 veces más rápido que la respuesta aceptada (por Mrchief). Esta debería ser la respuesta real
Kamarey
115

Refactorizando el código de Mrcheif para aprovechar Linq (es decir .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);
}

:)

Pure.Krome
fuente
Tengo algunas direcciones IP como "Inter Network" y esta solución realmente funciona y devuelve la correcta. El otro de Mrchief me da el último. Entonces, en realidad, este debería ser el correcto;)
Keenora Fluffball
26
@KeenoraFluffball: este te da el primero, mientras que este te da el último (o viceversa, depende de cómo se construya la lista). De cualquier manera, ninguno de los dos es correcto: si se le proporciona más de 1 dirección IP, debe saber qué red está utilizando. Adivinar tomando la primera o la última no es la solución correcta.
gbjbaanb
Es posible que también desee incluir AddressFamily.InterNetworkV6
joelsand
la devolución de nulo si la red no está disponible no es útil si también tiene que manejar PC independientes. Lo reemplacé con "return IPAddress.Loopback;" que corresponde al número especial de IP 127.0.0.1.
Christian el
109

Sé que esto puede estar pateando un caballo muerto, pero tal vez esto pueda ayudar a alguien. He buscado por todas partes una forma de encontrar mi dirección IP local, pero en todas partes me dice que use:

Dns.GetHostEntry(Dns.GetHostName());

No me gusta para nada porque solo obtiene todas las direcciones asignadas a su computadora. Si tiene varias interfaces de red (que prácticamente todas las computadoras tienen hoy en día) no tiene idea de qué dirección va con qué interfaz de red. Después de hacer un montón de investigación, creé una función para usar la clase NetworkInterface y extraer la información de ella. De esta manera puedo decir qué tipo de interfaz es (Ethernet, inalámbrica, loopback, túnel, etc.), si está activa o no, y SOOO mucho más.

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

Ahora para obtener la dirección IPv4 de su interfaz de red Ethernet, llame:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

O tu interfaz inalámbrica:

GetLocalIPv4(NetworkInterfaceType.Wireless80211);

Si intenta obtener una dirección IPv4 para una interfaz inalámbrica, pero su computadora no tiene una tarjeta inalámbrica instalada, solo devolverá una cadena vacía. Lo mismo con la interfaz Ethernet.

¡Espero que esto ayude a alguien! :-)

EDITAR:

Se señaló (gracias @NasBanov) que, aunque esta función consiste en extraer la dirección IP de una manera mucho mejor que usarla, Dns.GetHostEntry(Dns.GetHostName())no funciona muy bien al admitir múltiples interfaces del mismo tipo o múltiples direcciones IP en una sola interfaz . Solo devolverá una única dirección IP cuando pueda haber varias direcciones asignadas. Para devolver TODAS estas direcciones asignadas, simplemente puede manipular la función original para que siempre devuelva una matriz en lugar de una sola cadena. Por ejemplo:

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

Ahora esta función devolverá TODAS las direcciones asignadas para un tipo de interfaz específico. Ahora, para obtener solo una cadena, puede usar la .FirstOrDefault()extensión para devolver el primer elemento de la matriz o, si está vacío, devolver una cadena vacía.

GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
compman2408
fuente
55
Esta es una mejor solución porque no hay usabilidad de DNS en muchos lugares y las interfaces pueden tener múltiples direcciones IP. También utilizo un método similar.
Mert Gülsoy
El problema con esto es que solo devuelve 1 dirección IP por interfaz ... la última IP, foreach.
Nas Banov
@ compman2408: no es cierto, una sola interfaz puede tener varias IP, consulte en.wikipedia.org/wiki/Multihoming#Variants para ver todos los combos. Un ejemplo obvio es cuando ejecuto tanto IPv4 como IPv6, pero en el pasado tuve un solo adaptador de ethernet que participó en múltiples redes IPv4. Inusual tal vez, pero perfectamente legal. Por ejemplo, para Windows, visite windowsnetworking.com/articles-tutorials/windows-2003/…
Nas Banov
@NasBanov Esta función solo está configurada para obtener direcciones IPv4, por lo que ni siquiera voy a hablar sobre IPv6 y su inutilidad actual. Soy consciente de que multihoming se conecta a múltiples redes en múltiples interfaces, sin embargo, nunca he oído hablar de conectarse a múltiples redes en la misma interfaz. Aunque parezca correcto que es realmente posible, el <1% de las personas que usan su NIC de esa manera solo tendrían que cambiar la función para devolver una matriz.
compman2408
1
Gracias por esto. Para su información, al menos en .NET 3.5 mono en OSX item.OperationalStatussiempre regresa Unknown.
gman
36

Aquí hay una versión modificada (de la de compman2408) que funcionó para mí:

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

Puede llamar a este método, por ejemplo, como:

GetLocalIPv4(NetworkInterfaceType.Ethernet);

El cambio: estoy recuperando la IP de un adaptador que tiene asignada una IP de puerta de enlace. Segundo cambio: agregué docstrings y break para hacer que este método sea más eficiente.

Gerardo H
fuente
2
Solución inteligente Ahora estoy usando esto.
RQDQ
44
Tiene el mismo problema que el código del que se deriva: solo devuelve una de las IP, una IP aleatoria de muchas, que no tiene que ser la que necesita. Se gana el ademiller.com/blogs/tech/2008/06/it-works-on-my-machine-award
Nas Banov
1
@NasBanov, claro que lo gané, como lo digo en mi publicación: "que funcionó para mí". :-)
Gerardo H
Este es el camino a seguir, gracias por esto. Cuando tiene interruptores de bucle invertido para emuladores instalados, todas las otras variantes fallan mientras esta tiene éxito.
DiamondDrake
1
¿Por qué solo devuelve la última dirección IP que encontró, no la primera? Un simpel breaken lo más interno ifo a returnharía el truco.
Martin Mulder
20

Este es el mejor código que encontré para obtener la IP actual, evitando obtener el host VMWare u otra dirección IP no válida.

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()
        : "";
}
rodcesar.santos
fuente
Probablemente deberías explicar por qué este código es la solución para la respuesta. ¿Puede obtener una respuesta a la pregunta si está conectado a Internet y esto genera un error?
Philipp M
Las otras formas no utilizan la validación IsDnsEligible y PrefixOrigin.
rodcesar.santos
@PhilippM Si la dirección no es elegible para DNS, es una IP interna reservada. No es el proveedor de internet host. Y si PrefixOrigin fue suministrado por un servidor DHCP, es posible que esta sea la mejor opción de dirección. ¡Esta es la función única que me funciona!
rodcesar.santos
1
@ user1551843 - eso fue genial, gracias. Estaba usando el viejo método GetHostByName depreciado pero estaba devolviendo la IP de un adaptador VMWare :)
Jason Newland
Esta fue la única solución que funcionó para mí en vpn + wireless. Gracias.
jay-danger
12

Creo que usar LinQ es más fácil:

Dns.GetHostEntry(Dns.GetHostName())
   .AddressList
   .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
   .ToString()
Kapé
fuente
14
Eso no es LINQ, son métodos de extensión y lambdas. Hay una diferencia
Mark
10
@Mark: si no agrega "using System.Linq;" sin embargo
BornToCode
55
Esto se debe a que el método de extensión está en la clase Enumerable que está en el espacio de nombres System.Linq. Todavía no es LINQ.
Marcar
20
Mark, incluso en esta forma corta, la declaración está usando LINQ-to-Objects presentada con la sintaxis del método (lambda). La sintaxis de consulta es simplemente un azúcar sintáctico que se compila en una cadena de llamadas al método de extensión IEnumerable, que es lo que es LINQ-to-objects. Fuentes: autor de un proveedor LINQ-to-SQL y una serie de artículos sobre el tema.
constantine g
9

Para reír, pensé que trataría de obtener una sola instrucción LINQ utilizando el nuevo operador condicional nulo C # 6. Parece bastante loco y probablemente terriblemente ineficiente, pero funciona.

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

Lógica cortesía de Gerardo H(y por referencia compman2408).

Stajs
fuente
Definitivamente divertido (+1), pero en realidad no necesita ser ineficiente en absoluto. Me recuerda a la programación en LISP o Forth :-)
Roland
6

Otra forma de obtener IP usando la expresión 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();
}
Amirhossein Yari
fuente
5

@mrcheif Encontré esta respuesta hoy y fue muy útil, aunque devolvió una IP incorrecta (no debido a que el código no funcionara), pero dio una IP entre redes incorrecta cuando tienes cosas como Himachi ejecutándose.

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;
}
Jordan Trainor
fuente
2
¿Te refieres a Logmein Hamachi? Es una solución VPN y juega con la pila de red. Además, al ser una VPN, parece razonable que devuelva la IP asignada a la VPN cuando está conectada (solo supongo).
Mrchief
2
Completamente poco confiable. No solo 192.0.0.0/8no es una prueba correcta para una dirección IP privada (hay 3 rangos, todos diferentes de este), sino que puede ser un rango de red corporativa, por lo que no es tanto "local".
ivan_pozdeev
5

Probado con una o varias tarjetas LAN y máquinas virtuales

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;
    }
Shanewaj
fuente
Tenga en cuenta que este solo funciona para Ethernet. Elimine la restricción NetworkInterfaceType para admitir wi-fi.
scor4er
3

Solo una versión actualizada mía 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;
}
Giusepe
fuente
2

Requisitos previos: debe agregar la referencia System.Data.Linq y referirla

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

También estaba luchando para obtener la IP correcta.

Probé una variedad de soluciones aquí, pero ninguna me proporcionó el efecto deseado. Casi todas las pruebas condicionales que se proporcionaron no provocaron el uso de ninguna dirección.

Esto es lo que funcionó para mí, espero que ayude ...

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);
UberBiza
fuente
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();
Naimish Mungara
fuente
str siempre está vacío
aj.toulan
1

Tenga en cuenta que, en el caso general, podría tener varias traducciones NAT y varios servidores dns, cada uno operando en diferentes niveles de traducción NAT.

¿Qué sucede si tiene NAT de nivel de operador y desea comunicarse con otros clientes del mismo operador? En el caso general, nunca se sabe con certeza porque puede aparecer con diferentes nombres de host en cada traducción NAT.

sgjsfth sthseth
fuente
1

Obsoleto desaparecido, esto me funciona

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

Actualizando la respuesta de Mrchief con Linq, tendremos:

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

Esto devuelve direcciones de cualquier interfaz que tenga direcciones de puerta de enlace y direcciones de unidifusión en dos listas separadas, 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());
}
Michael Jordan
fuente
Solución ordenada :)
Johan Franzén
1

Ya hay muchas respuestas, pero sigo aportando la mía:

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

Un trazador de líneas:

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

nota: Busque desde el final porque aún funciona después de que algunas interfaces se hayan agregado al dispositivo, como MobileHotspot, VPN u otros adaptadores virtuales sofisticados.

nyconing
fuente
1
Entonces, si mi IP local es 10.0.2.3, ¿no se encuentra? Eso es realmente extraño en este código.
frankhommers
Se ha dicho que @frankhommers verifica solo el bloque de 16 bits
nyconing
Los bloques de 16 bits también pueden ser algo más que 192.168
frankhommers
0

Además, solo un código simple para obtener Client Ip:

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

Espero que sea de ayuda.

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

ingrese la descripción de la imagen aquí

Eran Peled
fuente
55
Su respuesta debe contener una descripción de cómo funciona para el caso de OP y también para futuros lectores.
Ronak Dhoot
Es mejor incluir una explicación de su respuesta para futuros lectores.
Nicolas Gervais
0

Se modificó el código de compman2408 para poder iterar a través de cada uno 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;
}

Y puedes llamarlo así:

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

Debajo de la misma acción

Función LocalIP ()

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

txtIP.Text = Host

Volver verdadero

Función final

YongJae Kim
fuente
El siguiente ejemplo es la misma acción Función 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 línea de código: D

Oso peludo
fuente
77
Puede lanzar una OutOfRangeException en algunos casos.
Loudenvier
55
Además, ¿cómo sabes cuál quieres? Lo que es correcto para ti podría estar mal para otra persona.
Mark
-3

Si tiene máquinas virtuales o tarjetas de red adicionales, puede haber otros valores en la lista de direcciones. Mi sugerencia es verificar las entradas de la lista de direcciones e imprimir lo que sea apropiado. En mi caso, la entrada 3 era la dirección ipv4 de mi máquina

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

No olvides agregar using System.Net;

Bibaswann Bandyopadhyay
fuente
1
Corrección; TODOS ellos son la dirección IP de su máquina. Sin embargo, cuál quieres es otra historia. Tenga en cuenta que el orden puede cambiar y, debido al método que está utilizando, siempre estará adivinando.
Mark
Eso es lo que dije, deberías revisar las entradas de la lista de direcciones, y sí, es adivinar, pero después de ver todas las entradas, adivinar no es muy difícil
Bibaswann Bandyopadhyay
¿Cómo sabrías cuál es el apropiado? Usando la solución de compman2048, al menos sabría cuál está vinculada a qué interfaz.
Mark
Esa solución no funcionó en mi computadora, porque tengo 2 interfaces wlan, 2 máquinas virtuales y 1 emulador, así que obtuve muchas IP. Pero si está buscando una dirección interna proporcionada por el enrutador, comenzará con 192 o 172 o 10, así es como lo entendí
Bibaswann Bandyopadhyay
A menos que su enrutador distribuya IP públicas, lo cual es poco común pero posible.
Mark