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

Sai*_*int 25 .net c# network-programming ip-address

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

Tim*_*ker 51

你必须做一个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
}
Run Code Online (Sandbox Code Playgroud)

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

如果您只是在寻找信息并且不关心如何获取信息,则可以使用NMap.命令如下

nmap -sP 192.168.1.0/24
Run Code Online (Sandbox Code Playgroud)

编辑:

就速度而言,由于您在本地网络上,因此您可以大大减少超时间隔,因为您的计算机不应该花费超过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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 多个独立的 IP 子网没有理由共享同一个物理 LAN,因此这种过程是有限的(并且不会区分由交换机连接的 LAN)。这还是在考虑 VLAN 之前的情况。这个问题的真正答案是“一般来说没有这样的方法”。实际上,除非其他节点不响应 ping,否则 ping 无需命中网关即可到达的每个地址(即 this-IP &amp; mask == other-IP &amp; mask)将起作用。 (2认同)