14

我正在开发一个家庭安全应用程序。我想做的一件事是根据我是否在家自动关闭和打开它。我有一部带 Wifi 的手机,当我在家时,它会自动连接到我的网络。

电话通过 DHCP 连接并获取其地址。虽然我可以将其配置为使用静态 IP,但我宁愿不这样做。C#/.Net 中是否有任何类型的“Ping”或等效项可以获取设备的 MAC 地址并告诉我它当前是否在网络上处于活动状态?

编辑:澄清一下,我在 PC 上运行软件,我希望能够在同一个 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;
}
4

2 回答 2

2

另一种方法是使用pingarp工具。由于 ARP 数据包只能留在同一个广播域中,因此您可以 ping 网络的广播地址,每个客户端都会回复 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 分钟或更短时间就会被清除一次。

于 2010-04-02T17:43:55.013 回答
1

您可以使用RARP 协议广播谁拥有该 MAC 地址的请求。所有者将使用其 IP 地址进行响应。我不知道要推荐的 RARP 工具或库,因此您可以考虑编写自己的网络层来发送/接收这些数据包。

于 2010-04-02T14:33:55.783 回答