¿Cómo obtener IP de todos los hosts en LAN?

Necesito enumerar las direcciones IP de todos los hosts conectados en mi LAN. ¿Cuál es la forma más simple de hacer esto?

Tendrás que hacer un barrido de ping. Hay una clase Ping en el espacio de nombres System.Net. El ejemplo sigue. También esto solo es posible si sus computadoras no tienen firewalls funcionando. Si tienen habilitado un firewall, no hay forma de determinar esta información, salvo hacer consultas SNMP en sus switches.

System.Net.NetworkInformation.Ping p = new System.Net.NetworkInformation.Ping(); System.Net.NetworkInformation.PingReply rep = p.Send("192.168.1.1"); if (rep.Status == System.Net.NetworkInformation.IPStatus.Success) { //host is active } 

El otro problema es determinar qué tan grande es su red. En la mayoría de los hogares, su máscara de red tendrá 24 bits. Esto significa que está configurado en 255.255.255.0. Si su puerta de enlace es 192.168.1.1, esto significa que las direcciones válidas en su red serán 192.168.1.1 a 192.168.1.254. Aquí hay una calculadora de IP para ayudar. Tendrás que recorrer cada dirección y hacer ping en la dirección usando la clase Ping y verificar PingReply.

Si solo está buscando la información y no le preocupa cómo la obtiene, puede usar NMap. El comando sería el siguiente

 nmap -sP 192.168.1.0/24 

EDITAR:

En lo que respecta a la velocidad, dado que se encuentra en una red local, puede reducir considerablemente el intervalo de tiempo de espera ya que sus máquinas no deberían tardar más de 100 milisegundos en responder. También puede usar SendAsync para hacer ping a todos ellos en paralelo. El siguiente progtwig hará ping a la dirección 254 en menos de medio segundo.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net.NetworkInformation; using System.Diagnostics; using System.Net; using System.Threading; using System.Net.Sockets; namespace ConsoleApplication1 { class Program { static CountdownEvent countdown; static int upCount = 0; static object lockObj = new object(); const bool resolveNames = true; static void Main(string[] args) { countdown = new CountdownEvent(1); Stopwatch sw = new Stopwatch(); sw.Start(); string ipBase = "10.22.4."; for (int i = 1; i < 255; i++) { string ip = ipBase + i.ToString(); Ping p = new Ping(); p.PingCompleted += new PingCompletedEventHandler(p_PingCompleted); countdown.AddCount(); p.SendAsync(ip, 100, ip); } countdown.Signal(); countdown.Wait(); sw.Stop(); TimeSpan span = new TimeSpan(sw.ElapsedTicks); Console.WriteLine("Took {0} milliseconds. {1} hosts active.", sw.ElapsedMilliseconds, upCount); Console.ReadLine(); } static void p_PingCompleted(object sender, PingCompletedEventArgs e) { string ip = (string)e.UserState; if (e.Reply != null && e.Reply.Status == IPStatus.Success) { if (resolveNames) { string name; try { IPHostEntry hostEntry = Dns.GetHostEntry(ip); name = hostEntry.HostName; } catch (SocketException ex) { name = "?"; } Console.WriteLine("{0} ({1}) is up: ({2} ms)", ip, name, e.Reply.RoundtripTime); } else { Console.WriteLine("{0} is up: ({1} ms)", ip, e.Reply.RoundtripTime); } lock(lockObj) { upCount++; } } else if (e.Reply == null) { Console.WriteLine("Pinging {0} failed. (Null Reply object?)", ip); } countdown.Signal(); } } } 

EDITAR: Después de usarlo un poco, modifiqué el progtwig para generar un recuento de cuántas IP respondieron. Hay un const bool que si se establece en verdadero, hará que el progtwig resuelva los nombres de host de las direcciones IP. Sin embargo, esto ralentiza significativamente el escaneo. (menos de medio segundo a 16 segundos) También descubrí que si la dirección IP se especifica incorrectamente (cometí un error), el objeto de respuesta puede ser nulo, así que lo manejé.

Tendría que crear un rango de direcciones (por ejemplo, 192.168.0.1 – 192.168.255.254) y hacer ping a cada una de esas direcciones. Si se recibe una respuesta, ese host está activo.

Tutorial asincrónico de ping:

http://www.geekpedia.com/tutorial234_Asynchronous-Ping-using-Csharp.html

Sin embargo, algunos sistemas operativos más nuevos bloquean las solicitudes de ping (ICMP). Debería estar deshabilitado en el firewall de cada computadora para que reciba una respuesta.

Puede hacer ping al rango de direcciones y observar si un host respondió. Por supuesto, esto requerirá que el host responda a los paquetes de ping.

Puedes hacerlo todo en código administrado. Lo hago usando System.DirectoryServices y System.Net. Básicamente obtengo los nombres de las computadoras locales de DirectoryServices (manejo de dominios y grupos de trabajo a medida que avanzo) y luego obtengo las direcciones IP de cada host de System.Net.Dns. Aquí hay todo empaquetado en una clase práctica …

 public class NetworkComputer { private string _domain; private string _name; private IPAddress[] _addresses = null; public string Domain { get { return _domain; } } public string Name { get { return _name; } } public IPAddress[] Addresses { get { return _addresses; } } private NetworkComputer(string domain, string name) { _domain = domain; _name = name; try { _addresses = Dns.GetHostAddresses(name); } catch { } } public static NetworkComputer[] GetLocalNetwork() { var list = new List(); using(var root = new DirectoryEntry("WinNT:")) { foreach(var _ in root.Children.OfType()) { switch(_.SchemaClassName) { case "Computer": list.Add(new NetworkComputer("", _.Name)); break; case "Domain": list.AddRange(_.Children.OfType().Where(__ => (__.SchemaClassName == "Computer")).Select(__ => new NetworkComputer(_.Name, __.Name))); break; } } } return list.OrderBy(_ => _.Domain).ThenBy(_ => _.Name).ToArray(); } } 

Luego solo llame al método estático para obtener una matriz de sus computadoras LAN …

 var localComputers = NetworkComputer.GetLocalNetwork(); 

En lugar de organizar una ping-party salvaje, posiblemente (¡realmente no sé exactamente!) Usar NetBIOS (¿se puede solicitar la tabla de nombres de Netbios?) http://technet.microsoft.com/en-us/library/cc757216% 28WS.10% 29.aspx . ¿O por qué no preguntar a su servidor DHCP?

 namespace WindowsFormsApplication1 { class WifiInformation { static CountdownEvent countdown; static int upCount = 0; static object lockObj = new object(); const bool resolveNames = true; static void Main(string[] args) { string ipBase = getIPAddress(); string[] ipParts = ipBase.Split('.'); ipBase = ipParts[0] + "." + ipParts[1] + "." + ipParts[2] + "."; for (int i = 1; i < 255; i++) { string ip = ipBase + i.ToString(); Ping p = new Ping(); p.PingCompleted += new PingCompletedEventHandler(p_PingCompleted); p.SendAsync(ip, 100, ip); } Console.ReadLine(); } static void p_PingCompleted(object sender, PingCompletedEventArgs e) { string ip = (string)e.UserState; if (e.Reply != null && e.Reply.Status == IPStatus.Success) { if (resolveNames) { string name; try { IPHostEntry hostEntry = Dns.GetHostEntry(ip); name = hostEntry.HostName; } catch (SocketException ex) { name = "?"; } Console.WriteLine("{0} ({1}) is up: ({2} ms)", ip, name, e.Reply.RoundtripTime); } else { Console.WriteLine("{0} is up: ({1} ms)", ip, e.Reply.RoundtripTime); } lock (lockObj) { upCount++; } } else if (e.Reply == null) { Console.WriteLine("Pinging {0} failed. (Null Reply object?)", ip); } } public static string getIPAddress() { IPHostEntry host; string localIP = ""; host = Dns.GetHostEntry(Dns.GetHostName()); foreach (IPAddress ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) { localIP = ip.ToString(); } } return localIP; } } } 

Haga ping a la dirección IP de difusión global (192.168.1.255)

Normalmente obtendremos la respuesta de todo el host conectado a la LAN. O si tiene una red particular para la LAN, haga ping a esa ID de difusión de las redes (es decir, la última dirección IP en ese rango).

Entonces puedes saber toda la dirección IP conectada al host en lan.