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