Я разрабатываю домашнее приложение защиты. Одна вещь, которую я хотел бы сделать, автоматически выключают и включают его на основе того, являюсь ли я дома. У меня есть телефон с Wi-Fi, который автоматически соединяется с моей сетью, когда я дома.
Телефон соединяет и получает свой адрес через DHCP. В то время как я мог настроить его для использования статического IP, я буду скорее нет. Действительно ли там кто-либо - вид 'Ping' или эквивалентный в C# / .NET, который может взять MAC-адрес устройства и сказать мне, в настоящее время ли это активно в сети?
Править: Для разъяснения я запускаю программное обеспечение на ПК, который я хотел бы иметь смочь обнаружить телефон на той же LAN.
Править: Вот код, который я придумал благодаря справке spoulson. Это надежно обнаруживает, является ли какой-либо из телефонов, которыми я интересуюсь, в доме.
private bool PhonesInHouse()
{
Ping p = new Ping();
// My home network is 10.0.23.x, and the DHCP
// pool runs from 10.0.23.2 through 10.0.23.127.
int baseaddr = 10;
baseaddr <<= 8;
baseaddr += 0;
baseaddr <<= 8;
baseaddr += 23;
baseaddr <<= 8;
// baseaddr is now the equivalent of 10.0.23.0 as an int.
for(int i = 2; i<128; i++) {
// ping every address in the DHCP pool, in a separate thread so
// that we can do them all at once
IPAddress ip = new IPAddress(IPAddress.HostToNetworkOrder(baseaddr + i));
Thread t = new Thread(() =>
{ try { Ping p = new Ping(); p.Send(ip, 1000); } catch { } });
t.Start();
}
// Give all of the ping threads time to exit
Thread.Sleep(1000);
// We're going to parse the output of arp.exe to find out
// if any of the MACs we're interested in are online
ProcessStartInfo psi = new ProcessStartInfo();
psi.Arguments = "-a";
psi.FileName = "arp.exe";
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
bool foundone = false;
using (Process pro = Process.Start(psi))
{
using (StreamReader sr = pro.StandardOutput)
{
string s = sr.ReadLine();
while (s != null)
{
if (s.Contains("Interface") ||
s.Trim() == "" ||
s.Contains("Address"))
{
s = sr.ReadLine();
continue;
}
string[] parts = s.Split(new char[] { ' ' },
StringSplitOptions.RemoveEmptyEntries);
// config.Phones is an array of strings, each with a MAC
// address in it.
// It's up to you to format them in the same format as
// arp.exe
foreach (string mac in config.Phones)
{
if (mac.ToLower().Trim() == parts[1].Trim().ToLower())
{
try
{
Ping ping = new Ping();
PingReply pingrep = ping.Send(parts[0].Trim());
if (pingrep.Status == IPStatus.Success)
{
foundone = true;
}
}
catch { }
break;
}
}
s = sr.ReadLine();
}
}
}
return foundone;
}
Другой подход заключается в использовании инструментов ping
и arp
. Поскольку ARP-пакеты могут находиться только в одном широковещательном домене, вы можете пинговать широковещательный адрес вашей сети, и каждый клиент будет отвечать ARP-ответом. Каждый из этих ответов кэшируется в вашей ARP-таблице, которую можно просмотреть с помощью команды arp -a
. Итак, сводка:
rem Clear ARP cache
netsh interface ip delete arpcache
rem Ping broadcast addr for network 192.168.1.0
ping -n 1 192.168.1.255
rem View ARP cache to see if the MAC addr is listed
arp -a
Некоторые из этих действий можно выполнить в управляемом коде, например, в пространстве имен System.Net.NetworkInformation
.
Примечание: Очистка ARP-кэша может незначительно повлиять на производительность сети, поскольку очищаются кэшированные записи других локальных серверов. Однако кэш обычно очищается каждые 20 минут или реже.
Вы можете использовать протокол RARP для широковещательной рассылки запроса о том, кто владеет этим MAC-адресом. Владелец ответит своим IP-адресом. Я не знаю инструмента или библиотеки RARP, которые можно было бы порекомендовать, поэтому вы можете подумать о написании собственного сетевого уровня для отправки / получения этих пакетов.