Тебе придется сделать пинг. В пространстве имен 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 и проверить PingReply.
Если вы просто ищете информацию и не интересуетесь, как вы ее получаете, вы можете использовать NMap. Команда будет выглядеть следующим образом:
nmap -sP 192.168.1.0/24
EDIT:
Что касается скорости, то, поскольку вы находитесь в локальной сети, вы можете значительно сократить интервал времени ожидания, поскольку вашим машинам не требуется более 100 миллисекунд для ответа. Вы также можете использовать SendAsync, чтобы пинговать их всех параллельно. Следующая программа будет пинговать адрес 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-адрес указан неверно (сам сделал опечатку), объект ответа может быть нулевым, поэтому я обработал это.