c# - servidor - Obtener dirección IP local
obtener la ip de una maquina c# (21)
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 me interesa 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 entonces para obtener la dirección IP de la LAN?
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;
}
@mrcheif Encontré esta respuesta hoy y fue muy útil a pesar de que devolvió una IP incorrecta (no debido a que el código no funcionó), pero dio una IP de red incorrecta cuando se está ejecutando 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;
}
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;
}
Aquí hay una versión modificada (de la de compman2408) que funcionó para mí:
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;
}
El cambio: estoy recuperando la IP de un adaptador que tiene asignada una IP de puerta de enlace.
Aquí viene un 1-liner completamente funcional y sólido para la pregunta de la dirección IP local. Hecho con el lenguaje de ejecución paralelo Dyalog APL. Curiosamente, esta pieza menor de código admite 0, 1 o varios adaptadores IPv4: el resultado será una matriz con longitud 0, 1 o n de vectores de texto incluidos.
Sobre todo por su confusión, supongo :-)
#.Dns.(a.AddressFamily.(⎕THIS=InterNetwork)/a←(GetHostEntry GetHostName).AddressList).ToString
Devoluciones (para esta computadora): 192.168.0.100 (<- vector en caja de un elemento, el primer elemento es un vector de texto de 13 caracteres)
Creo que usar LinQ es más fácil:
Dns.GetHostEntry(Dns.GetHostName())
.AddressList.First(
f => f.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
.ToString()
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()
: "";
}
Existe una forma más precisa cuando hay varias direcciones IP disponibles en la máquina local. Connect
un socket UDP y lea 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();
}
Connect
en 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" y configura los campos correspondientes. Esto incluye verificar la existencia de la ruta hacia el destino de acuerdo con la tabla de enrutamiento del sistema y configurar el punto final local en consecuencia. La última parte parece estar sin documentar 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 en Windows y 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 se ha establecido una conexión real, por lo tanto, la IP remota especificada puede ser inalcanzable.
Obsoleto desaparecido, esto me funciona
public static IPAddress GetIPAddress()
{
IPAddress ip = Dns.GetHostAddresses(Dns.GetHostName()).Where(address =>
address.AddressFamily == AddressFamily.InterNetwork).First();
return ip;
}
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();
}
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 comprobar si estás conectado o no:
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
Para reírme, pensé que intentaría obtener una sola declaración LINQ mediante el uso del nuevo operador condicional nulo C # 6. Parece bastante loco y probablemente horriblemente ineficiente, pero funciona.
private string GetLocalIPv4(NetworkInterfaceType type = NetworkInterfaceType.Ethernet)
{
// Bastardized from: http://.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
).
Refactorización del 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);
}
:)
Requisitos previos: tiene que 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));
Sé que esto puede ser patear a un caballo muerto, pero tal vez esto pueda ayudar a alguien. He buscado por todos lados la forma de encontrar mi dirección IP local, pero en todas partes encuentro que dice usar:
Dns.GetHostEntry(Dns.GetHostName());
No me gusta esto en absoluto porque solo obtiene todas las direcciones asignadas a su computadora. Si tiene varias interfaces de red (que casi todas las computadoras tienen hoy en día), no tiene idea de qué dirección va con qué interfaz de red. Después de investigar un poco, creé una función para usar la clase NetworkInterface y sacar la información de ella. De esta manera puedo saber qué tipo de interfaz es (Ethernet, inalámbrica, de bucle invertido, 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 llamada de interfaz de red Ethernet:
GetLocalIPv4(NetworkInterfaceType.Ethernet);
O su 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 a @NasBanov) que a pesar de que esta función trata de extraer la dirección IP de una manera mucho mejor que usar Dns.GetHostEntry(Dns.GetHostName())
no funciona muy bien para soportar múltiples interfaces de mismo tipo o múltiples direcciones IP en una sola interfaz. Solo devolverá una única dirección IP cuando haya múltiples direcciones asignadas. Para devolver TODAS estas direcciones asignadas, simplemente podría 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 una sola cadena, puede usar la extensión .FirstOrDefault()
para devolver el primer elemento de la matriz o, si está vacío, devolver una cadena vacía.
GetLocalIPv4(NetworkInterfaceType.Ethernet).FirstOrDefault();
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 imprimirlas según corresponda. 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 olvide agregar using System.Net;
Solo una versión actualizada de la 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 (NetworkInterface networkInterface in networkInterfaces)
{
var adapterProperties = networkInterface.GetIPProperties();
if (adapterProperties.GatewayAddresses.FirstOrDefault() != null)
{
foreach (UnicastIPAddressInformation ip in networkInterface.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
return ip.Address;
}
}
}
}
return null;
}
También estaba luchando para obtener la IP correcta.
Intenté varias soluciones aquí, pero ninguna me proporcionó el efecto deseado. Casi todas las pruebas condicionales que se proporcionaron no permitieron 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);
Tenga en cuenta que, en el caso general, podría tener múltiples traducciones de NAT y varios servidores dns, cada uno operando en diferentes niveles de traducción de NAT.
¿Qué sucede si tiene un NAT de nivel de operador y desea comunicarse con otros clientes del mismo proveedor? En el caso general, nunca se sabe con seguridad porque puede aparecer con diferentes nombres de host en cada traducción de NAT.
Dns.GetHostEntry(Dns.GetHostName()).AddressList[1]
una línea de código: D
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();