从C#中的IP获取本地网络上的计算机MAC地址

我正在尝试编写一个函数,它将一个IP address作为参数,并在我的本地网络上查询该机器的MAC address

我已经看到许多获得本地机器自己的MAC address例子,但是没有(我发现)似乎在查询本地网络机器。

我知道这样的任务是可以实现的,因为这种Wake on LAN扫描软件扫描本地IP范围并返回所有机器上的MAC地址/主机名。

谁能告诉我在哪里开始尝试编写一个函数来实现C#中的这个function? 任何帮助,将不胜感激。 谢谢

编辑:

根据Marco Mp在下面的评论,使用了ARP表。 arpclass

 public string GetMacAddress(string ipAddress) { string macAddress = string.Empty; System.Diagnostics.Process pProcess = new System.Diagnostics.Process(); pProcess.StartInfo.FileName = "arp"; pProcess.StartInfo.Arguments = "-a " + ipAddress; pProcess.StartInfo.UseShellExecute = false; pProcess.StartInfo.RedirectStandardOutput = true; pProcess.StartInfo.CreateNoWindow = true; pProcess.Start(); string strOutput = pProcess.StandardOutput.ReadToEnd(); string[] substrings = strOutput.Split('-'); if (substrings.Length >= 8) { macAddress = substrings[3].Substring(Math.Max(0, substrings[3].Length - 2)) + "-" + substrings[4] + "-" + substrings[5] + "-" + substrings[6] + "-" + substrings[7] + "-" + substrings[8].Substring(0, 2); return macAddress; } else { return "not found"; } } 

很晚编辑:在开源项目iSpy( https://github.com/ispysoftware/iSpy )他们使用这个代码,这是一个更好的

  public static void RefreshARP() { _arpList = new Dictionary(); _arpList.Clear(); try { var arpStream = ExecuteCommandLine("arp", "-a"); // Consume first three lines for (int i = 0; i < 3; i++) { arpStream.ReadLine(); } // Read entries while (!arpStream.EndOfStream) { var line = arpStream.ReadLine(); if (line != null) { line = line.Trim(); while (line.Contains(" ")) { line = line.Replace(" ", " "); } var parts = line.Trim().Split(' '); if (parts.Length == 3) { string ip = parts[0]; string mac = parts[1]; if (!_arpList.ContainsKey(ip)) _arpList.Add(ip, mac); } } } } catch (Exception ex) { Logger.LogExceptionToFile(ex, "ARP Table"); } if (_arpList.Count > 0) { foreach (var nd in List) { string mac; ARPList.TryGetValue(nd.IPAddress.ToString(), out mac); nd.MAC = mac; } } } 

https://github.com/ispysoftware/iSpy/blob/master/Server/NetworkDeviceList.cs

更新2更晚,但我认为最好,因为它使用正则表达式来更好地检查完全匹配。

 public string getMacByIp(string ip) { var macIpPairs = GetAllMacAddressesAndIppairs(); int index = macIpPairs.FindIndex(x => x.IpAddress == ip); if (index >= 0) { return macIpPairs[index].MacAddress.ToUpper(); } else { return null; } } public List GetAllMacAddressesAndIppairs() { List mip = new List(); System.Diagnostics.Process pProcess = new System.Diagnostics.Process(); pProcess.StartInfo.FileName = "arp"; pProcess.StartInfo.Arguments = "-a "; pProcess.StartInfo.UseShellExecute = false; pProcess.StartInfo.RedirectStandardOutput = true; pProcess.StartInfo.CreateNoWindow = true; pProcess.Start(); string cmdOutput = pProcess.StandardOutput.ReadToEnd(); string pattern = @"(?([0-9]{1,3}\.?){4})\s*(?([a-f0-9]{2}-?){6})"; foreach (Match m in Regex.Matches(cmdOutput, pattern, RegexOptions.IgnoreCase)) { mip.Add(new MacIpPair() { MacAddress = m.Groups["mac"].Value, IpAddress = m.Groups["ip"].Value }); } return mip; } public struct MacIpPair { public string MacAddress; public string IpAddress; } 
 using System.Net; using System.Runtime.InteropServices; [DllImport("iphlpapi.dll", ExactSpelling = true)] public static extern int SendARP(int DestIP, int SrcIP, [Out] byte[] pMacAddr, ref int PhyAddrLen); try { IPAddress hostIPAddress = IPAddress.Parse("XXX.XXX.XXX.XX"); byte[] ab = new byte[6]; int len = ab.Length, r = SendARP((int)hostIPAddress.Address, 0, ab, ref len); Console.WriteLine(BitConverter.ToString(ab, 0, 6)); } catch (Exception ex) { } 

或者使用PC名称

 try { Tempaddr = System.Net.Dns.GetHostEntry("DESKTOP-xxxxxx"); } catch (Exception ex) { } byte[] ab = new byte[6]; int len = ab.Length, r = SendARP((int)Tempaddr.AddressList[1].Address, 0, ab, ref len); Console.WriteLine(BitConverter.ToString(ab, 0, 6)); 

根据Marco Mp上面的评论,使用了ARP表。 arpclass

只是一个更好的可接受方法的版本。

  public string GetMacByIp( string ip ) { var pairs = this.GetMacIpPairs(); foreach( var pair in pairs ) { if( pair.IpAddress == ip ) return pair.MacAddress; } throw new Exception( $"Can't retrieve mac address from ip: {ip}" ); } public IEnumerable GetMacIpPairs() { System.Diagnostics.Process pProcess = new System.Diagnostics.Process(); pProcess.StartInfo.FileName = "arp"; pProcess.StartInfo.Arguments = "-a "; pProcess.StartInfo.UseShellExecute = false; pProcess.StartInfo.RedirectStandardOutput = true; pProcess.StartInfo.CreateNoWindow = true; pProcess.Start(); string cmdOutput = pProcess.StandardOutput.ReadToEnd(); string pattern = @"(?([0-9]{1,3}\.?){4})\s*(?([a-f0-9]{2}-?){6})"; foreach( Match m in Regex.Matches( cmdOutput, pattern, RegexOptions.IgnoreCase ) ) { yield return new MacIpPair() { MacAddress = m.Groups[ "mac" ].Value, IpAddress = m.Groups[ "ip" ].Value }; } } public struct MacIpPair { public string MacAddress; public string IpAddress; }