如何获取局域网中所有主机的IP?

时间:2010-10-28 12:15:55

标签: c# .net network-programming ip-address

我需要列出局域网中所有连接主机的IP地址。 最简单的方法是什么?

6 个答案:

答案 0 :(得分:50)

你必须进行ping扫描。 System.Net命名空间中有一个Ping类。示例如下。此外,只有在您的计算机没有运行防火墙的情况下才有可能。如果他们启用了防火墙,那么除了在交换机上执行SNMP查询之外,无法确定此信息。

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
}

另一个问题是确定您的网络规模。在大多数家庭情况下,您的网络掩码将是24位。这意味着它设置为255.255.255.0。如果您的网关是192.168.1.1,这意味着您网络上的有效地址将是192.168.1.1到192.168.1.254。这是IP Calculator的帮助。您必须遍历每个地址并使用Ping类ping地址并检查PingReply。

如果您只是在查找信息而不关心如何获取信息,则可以使用NMap。命令如下

nmap -sP 192.168.1.0/24

编辑:

就速度而言,由于您在本地网络上,因此您可以大大减少超时间隔,因为您的计算机不应该花费超过100毫秒的时间来回复。您还可以使用SendAsync并行ping它们。以下程序将在半秒内ping 254地址。

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

编辑:在我自己使用它之后,我修改了程序以输出响应了多少IP的计数。有一个const bool,如果设置为true,将导致程序解析IP的主机名。但这显着减慢了扫描速度。 (在半秒到16秒之内)还发现如果IP地址被错误指定(我自己写错了),回复对象可以为null,所以我处理了。

答案 1 :(得分:2)

您需要构建一个地址范围(例如192.168.0.1 - 192.168.255.254)并ping每个地址。如果收到响应,则该主机处于活动状态。

异步Ping教程:

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

但是,一些较新的操作系统会阻止ping请求(ICMP)。需要在每台计算机的防火墙中禁用此功能,以便您接收响应。

答案 2 :(得分:0)

您可以ping通地址范围并记下主机是否响应。当然,这将要求主机响应ping数据包。

答案 3 :(得分:0)

您可以在托管代码中完成所有操作。我使用System.DirectoryServices和System.Net来做。基本上我从DirectoryServices获取本地计算机的名称(处理域和工作组),然后从System.Net.Dns获取每个主机的IP地址。这里的所有东西都装在一个方便的课程中......

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

然后只需调用静态方法来获取LAN计算机的数组......

var localComputers = NetworkComputer.GetLocalNetwork();

答案 4 :(得分:-1)

你可能(我真的不确切知道!)而不是安排一个疯狂的ping方,而是使用NetBIOS(以某种方式请求netbios名称表?)http://technet.microsoft.com/en-us/library/cc757216%28WS.10%29.aspx。或者为什么不问你的DHCP服务器?

答案 5 :(得分:-3)

Ping到全局广播IP地址(192.168.1.255)

通常我们会收到连接到局域网的所有主机的回复。或者,如果您有任何特定的局域网,请ping该网络广播ID(即该范围内的最后一个IP地址)。

然后你就可以知道连接到局域网主机的所有IP地址。