2010-10-28 22 views
17

Ho bisogno di elencare gli indirizzi IP di tutti gli host collegati nella mia LAN. Qual è il modo più semplice per farlo?Come ottenere l'IP di tutti gli host nella LAN?

+1

Definire in contatto - si intende come attiva ? Sono firewall o possono essere pingati? – TomTom

+0

Sì, attivo. Possono essere firewall ma non necessariamente - Non lo so perché sono utente non amministratore. – Saint

+0

Qual è l'ambiente in cui si trova? Avete un interruttore gestito che fa SNMP? In tal caso, puoi semplicemente eseguire una query sull'interruttore per vedere chi è attivo. Se è un piccolo router domestico, sei sfortunato. –

risposta

40

Dovrai eseguire una scansione ping. Esiste una classe Ping nello spazio dei nomi System.Net. Segue un esempio. Anche questo è possibile solo se i tuoi computer non hanno firewall in esecuzione. Se hanno un firewall abilitato, non c'è modo di determinare queste informazioni a meno di fare query SNMP sui tuoi switch.

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 
} 

L'altro problema è determinare la larghezza della rete. Nella maggior parte delle situazioni domestiche, la tua maschera di rete sarà di 24 bit. Ciò significa che è impostato su 255.255.255.0. Se il tuo gateway è 192.168.1.1, significa che gli indirizzi validi sulla tua rete saranno 192.168.1.1 a 192.168.1.254. Ecco un IP Calculator per aiutare. Dovrai scorrere ogni indirizzo e eseguire il ping dell'indirizzo utilizzando la classe Ping e controllare PingReply.

Se stai solo cercando le informazioni e non sei interessato a come lo ottieni, puoi usare NMap. Il comando sarà il seguente

nmap -sP 192.168.1.0/24 

EDIT:

Per quanto riguarda la velocità va, visto che sei in una rete locale, è possibile ridurre l'intervallo di timeout considerevolmente le macchine non devono assumere più di 100 millisecondi per rispondere. È inoltre possibile utilizzare SendAsync per eseguire il ping di tutti in parallelo. Il seguente programma eseguirà il ping di 254 indirizzi in meno di mezzo secondo.

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

EDIT: Dopo qualche uso di esso me stesso, ho modificato il programma per produrre un conteggio di quanti IP risposto. C'è un booster const che, se impostato su true, farà sì che il programma risolva i nomi host degli IP. Ciò tuttavia rallenta notevolmente la scansione. (meno di mezzo secondo a 16 secondi) Inoltre, ho scoperto che se l'indirizzo IP è stato specificato in modo errato (fatto un errore), l'oggetto risposta può essere nullo, quindi l'ho gestito.

+0

@Tim, sai se Nmap ha un'API? – Brad

+0

Solo per avviso, RFC1918 dice che questi intervalli sono tutti validi per le LAN: 10.0.0.0 - 10.255.255.255, 172.16.0.0 - 172.31.255.255, 192.168.0.0 - 192.168.255.255 – joni

+1

@Brad, non sono sicuro di un'API completa, ma è progettato nello spirito di un normale programma UNIX, quindi è possibile eseguirlo facilmente tramite la riga di comando e acquisire l'output standard. Ci sono opzioni per formattare via XML così come un formato GREPable (IE, uso con regex). Per informazioni su come eseguire un comando e catturare l'output in C#, vedere questa risposta. http://stackoverflow.com/questions/3258704/issues-about-files-in-use-get-the-name-of-another-process-that-use-file/3258779#3258779 –

0

È possibile eseguire il ping dell'intervallo di indirizzi e notare se un host ha risposto. Naturalmente, questo richiederà all'host di rispondere ai pacchetti ping.

+0

Il ping ad esempio di 255 host è una sorta di consumo di tempo, penso di si. C'è un metodo più veloce? – Saint

+2

un secondo non richiede tempo. Basta colpire tutti i 255 ping allo stesso tempo, non uno dopo l'altro in attesa di timeout. – TomTom

+0

Come fare più veloce? Anche se faccio il ping di 10 host ci vogliono diversi secondi. – Saint

2

È necessario creare un intervallo di indirizzi (ad esempio 192.168.0.1 - 192.168.255.254) e eseguire il ping di ciascuno di questi indirizzi. Se viene ricevuta una risposta, quell'host è attivo.

Asynchronous Ping Tutorial:

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

Tuttavia, alcune richieste sistemi operativi più recenti blocco ping (ICMP). Questo dovrebbe essere disabilitato nel firewall su ciascun computer affinché tu possa ricevere una risposta.

-1

Invece di organizzare un ping-party selvaggio, è possibile (in realtà non so esattamente!) Utilizzare NetBIOS (richiedere il netbios nametable in qualche modo?) http://technet.microsoft.com/en-us/library/cc757216%28WS.10%29.aspx. O perché non chiedi al tuo server DHCP?

+1

È improbabile che il server DHCP restituisca ACTIVE. Sai solo di recente attivo: devi ancora eseguire il ping e potresti perdere alcune cose configurate staticamente. – TomTom

+0

sì, l'unico modo per essere sicuri sarebbe quello di cercare il tuo switch di rete e quindi seguire tutti i cavi .. – joni

-2

Ping per l'indirizzo globale di broadcast IP (192.168.1.255)

Normalmente si otterrà la risposta da tutti gli host collegato alla rete LAN .. O se una particolare rete per la LAN, ping a quella reti broadcast id (cioè l'ultimo indirizzo ip in quell'intervallo).

Quindi è possibile conoscere tutti gli indirizzi IP collegati all'host in lan.

+0

Cosa? Veramente ? –

+0

non sembra funzionare ... –

0

È possibile eseguire tutto in codice gestito. Lo faccio usando System.DirectoryServices e System.Net. Fondamentalmente ottengo i nomi dei computer locali da DirectoryServices (gestendo domini e gruppi di lavoro mentre procedo), quindi ottengo gli indirizzi IP di ogni host da System.Net.Dns. Ecco tutto quello confezionato in una classe a portata di mano ...

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<NetworkComputer>(); 
     using(var root = new DirectoryEntry("WinNT:")) { 
      foreach(var _ in root.Children.OfType<DirectoryEntry>()) { 
       switch(_.SchemaClassName) { 
        case "Computer": 
         list.Add(new NetworkComputer("", _.Name)); 
         break; 
        case "Domain": 
         list.AddRange(_.Children.OfType<DirectoryEntry>().Where(__ => (__.SchemaClassName == "Computer")).Select(__ => new NetworkComputer(_.Name, __.Name))); 
         break; 
       } 
      } 
     } 
     return list.OrderBy(_ => _.Domain).ThenBy(_ => _.Name).ToArray(); 
    } 
} 

Poi basta chiamare il metodo statico per ottenere un array dei computer della LAN ...

var localComputers = NetworkComputer.GetLocalNetwork(); 
-1
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; 
     } 
    } 
} 
Problemi correlati