我需要列出局域网中所有已连接主机的IP地址。 最简单的方法是什么?
我需要列出局域网中所有已连接主机的IP地址。 最简单的方法是什么?
您需要进行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
}
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
布尔值,如果设置为true,将导致程序解析IP的主机名。尽管这会显著减慢扫描速度(从不到半秒钟到16秒),但也可以发现,如果IP地址输入错误(我自己输错了),则回复对象可能为空,因此我进行了处理。
http://www.geekpedia.com/tutorial234_Asynchronous-Ping-using-Csharp.html
然而,一些较新的操作系统会阻止 ping 请求(ICMP)。为了让您收到响应,需要在每台计算机的防火墙中禁用它。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();
}
}
然后只需调用静态方法,即可获取您的局域网计算机数组...
var localComputers = NetworkComputer.GetLocalNetwork();
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;
}
}
}
向全局广播IP地址(192.168.1.255)发送Ping请求
通常情况下,我们将从连接到局域网的所有主机获得回复。或者,如果您有任何特定于局域网的网络,请ping该网络的广播ID(即该范围内的最后一个IP地址)。
然后,您就可以知道连接到局域网中的所有IP地址。
与其安排一个疯狂的 ping-party,你可能可以(我真的不确定!)使用 NetBIOS(以某种方式请求 netbios 名称表?)http://technet.microsoft.com/en-us/library/cc757216%28WS.10%29.aspx。或者为什么不问问你的 DHCP 服务器呢?