2010-10-28 42 views
17

Tôi cần liệt kê địa chỉ IP của tất cả các máy chủ được kết nối trong mạng LAN của mình. Cách đơn giản nhất để làm điều này là gì?Làm cách nào để nhận IP của tất cả các máy chủ trong mạng LAN?

+1

Xác định kết nối - bạn có ý nghĩa như hoạt động ? Chúng được tường lửa hay chúng có thể được ping? – TomTom

+0

Có, đang hoạt động. Chúng có thể được tường lửa nhưng không nhất thiết - Tôi không biết vì tôi là người dùng không phải quản trị viên. – Saint

+0

Môi trường này là gì? Bạn có một công tắc được quản lý có SNMP không? Nếu có, bạn chỉ có thể truy vấn nút chuyển để xem ai đang hoạt động. Nếu nó là một bộ định tuyến gia đình nhỏ, bạn sẽ không may mắn. –

Trả lời

40

Bạn sẽ phải thực hiện quét ping. Có một lớp Ping trong không gian tên System.Net. Ví dụ sau. Ngoài ra, điều này chỉ có thể xảy ra nếu máy tính của bạn không chạy tường lửa. Nếu họ đã bật tường lửa, sẽ không có cách nào để xác định thông tin này ngắn khi thực hiện các truy vấn SNMP trên thiết bị chuyển mạch của bạn.

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 
} 

Vấn đề khác là xác định mạng của bạn lớn đến mức nào. Trong hầu hết các tình huống gia đình, mặt nạ mạng của bạn sẽ là 24 bit. Điều này có nghĩa là thiết lập của nó là 255.255.255.0. Nếu cổng của bạn là 192.168.1.1, điều này có nghĩa là địa chỉ hợp lệ trên mạng của bạn sẽ là 192.168.1.1 đến 192.168.1.254. Đây là số IP Calculator để trợ giúp. Bạn sẽ phải lặp qua từng địa chỉ và ping địa chỉ bằng cách sử dụng lớp Ping và kiểm tra PingReply.

Nếu bạn chỉ tìm kiếm thông tin và không quan tâm đến cách bạn nhận được thông tin, bạn có thể sử dụng NMap. Lệnh sẽ như sau

nmap -sP 192.168.1.0/24 

EDIT:

Theo như tốc độ đi, kể từ khi bạn đang ở trên một mạng cục bộ, bạn có thể cắt giảm khoảng thời gian chờ đáng kể như máy của bạn không nên dùng nhiều hơn 100 mili giây để trả lời. Bạn cũng có thể sử dụng SendAsync để ping tất cả chúng song song. Chương trình sau sẽ ping địa chỉ 254 trong vòng nửa giây.

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: Sau khi tự mình sử dụng, tôi đã sửa đổi chương trình để kiểm tra số lượng IP đã trả lời. Có một bool const nếu được đặt thành true, sẽ khiến chương trình giải quyết tên máy chủ lưu trữ của IP. Tuy nhiên, điều này làm chậm quá trình quét. (dưới một nửa giây đến 16 giây) Cũng thấy rằng nếu địa chỉ IP được chỉ định không chính xác (thực hiện một lỗi chính tả), đối tượng trả lời có thể là null, vì vậy tôi đã xử lý điều đó.

+0

@Tim, bạn có biết Nmap có API không? – Brad

+0

Chỉ để thông báo, RFC1918 nói rằng các phạm vi này đều hợp lệ đối với mạng 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, không chắc chắn về API đầy đủ, nhưng nó được thiết kế theo tinh thần của một chương trình UNIX thông thường, vì vậy bạn có thể dễ dàng thực hiện nó thông qua dòng lệnh và bắt đầu ra chuẩn. Có các tùy chọn để định dạng thông qua định dạng XML cũng như định dạng GREPable (IE, sử dụng với regex). Để biết thông tin về cách thực hiện một lệnh và nắm bắt đầu ra trong C#, hãy xem câu trả lời này. http://stackoverflow.com/questions/3258704/issues-about-files-in-use-get-the-name-of-another-process-that-use-file/3258779#3258779 –

0

Bạn có thể ping dải địa chỉ và lưu ý nếu máy chủ phản hồi. Tất nhiên, điều này sẽ yêu cầu máy chủ phản hồi các gói ping.

+0

Pinging ví dụ 255 host là loại thời gian tiêu thụ-tôi nghĩ vậy. Có phương pháp nhanh hơn không? – Saint

+2

giây không mất thời gian. Chỉ cần nhấn hết tất cả 255 ping cùng một lúc, chứ không phải cái nào khác chờ hết thời gian chờ. – TomTom

+0

Làm thế nào để làm điều này nhanh hơn? Ngay cả khi tôi ping 10 máy chủ, nó mất vài giây. – Saint

2

Bạn cần tạo một dải địa chỉ (ví dụ: 192.168.0.1 - 192.168.255.254) và ping từng địa chỉ đó. Nếu một phản hồi được nhận, thì máy chủ đó đang hoạt động.

Asynchronous Ping Hướng dẫn:

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

Tuy nhiên, một số yêu cầu hệ điều hành khối ping mới hơn (ICMP). Điều này sẽ cần phải được vô hiệu hoá trong tường lửa trên mỗi máy tính để bạn nhận được phản hồi.

-1

Thay vì sắp xếp một nhóm ping hoang dã, bạn có thể có thể (tôi thực sự không biết chính xác!) Sử dụng NetBIOS (yêu cầu tên mạng bằng cách nào đó?) http://technet.microsoft.com/en-us/library/cc757216%28WS.10%29.aspx. Hoặc tại sao không hỏi máy chủ DHCP của bạn?

+1

Máy chủ DHCP sẽ không trả về ACTIVE. Bạn chỉ biết hoạt động gần đây - vẫn phải ping và bạn có thể bỏ lỡ một số nội dung được định cấu hình tĩnh. – TomTom

+0

vâng, cách duy nhất để chắc chắn sẽ là tìm kiếm công tắc mạng của bạn và sau đó thực hiện theo tất cả các loại cáp .. – joni

-2

Ping đến địa chỉ broadcast ip toàn cầu (192.168.1.255)

Thông thường chúng ta sẽ nhận được trả lời từ tất cả các máy chủ kết nối với mạng LAN .. Hoặc nếu bạn có bất kỳ mạng cụ thể cho lan, ping để mà mạng phát sóng id (tức là địa chỉ ip cuối cùng trong phạm vi đó).

Sau đó, bạn có thể biết tất cả địa chỉ IP được kết nối với máy chủ lưu trữ trong lan.

+0

Cái gì? Có thật không ? –

+0

dường như không hoạt động ... –

0

Bạn có thể thực hiện tất cả trong mã được quản lý. Tôi làm điều đó bằng cách sử dụng System.DirectoryServices và System.Net. Về cơ bản tôi nhận được tên của các máy tính địa phương từ DirectoryServices (xử lý các tên miền và nhóm làm việc khi tôi đi) sau đó nhận được địa chỉ IP của mỗi máy chủ từ System.Net.Dns. Dưới đây là tất cả mọi thứ hòa quyện trong một lớp tiện dụng ...

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

Sau đó chỉ cần gọi phương thức tĩnh để có được một loạt các máy tính mạng LAN của bạn ...

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; 
     } 
    } 
} 
Các vấn đề liên quan