如何查找外部设备的MAC地址?如何找到所有网络计算机的MAC地址?

问题描述 投票:0回答:2

我想在本地网络中搜索和查找特定设备并连接到它们。

为了验证我连接的计算机是否正确,我想首先获取网络中所有计算机的 MAC 地址,然后选择每次要进行的连接。

有人可以帮我解决这个问题吗?

到目前为止,我使用 C# 和 TCP 客户端类。
但我不知道如何找到另一台计算机的 MAC 地址,不是应用程序运行的计算机
我想找到我要连接的计算机的 MAC 地址。

c# tcp connection tcpclient mac-address
2个回答
0
投票

为了解决类似的任务,我创建了一个名为 ArpLookup (nuget) 的小型 MIT 许可库。

特点:

  • 直接从 C# 运行,无需创建任何
    ping
    arp
    进程
  • 支持Windows和Linux
  • 在 Linux 上提供了
    Async
    变体(它在 Windows 上也可以,但在那里不能真正异步)
  • 免费且开源

使用后

dotnet add package ArpLookup
像这样

using System.Net.NetworkInformation;
using ArpLookup;

// ...

PhysicalAddress mac = Arp.Lookup(IPAddress.Parse("1.2.3.4"));

PhysicalAddress mac = await Arp.LookupAsync(IPAddress.Parse("1.2.3.4"));

0
投票

使用所有 Windows 版本原生的

iphlpapi.dll

使用自定义 Ping 方法。

这个想法是如果没有返回 mac 则进行 ping 操作,这应该 mac 会更新 ARP 表。

⚠ 仅适用于 LAN

/// <summary>
/// Gets the MAC address associated with the specified IP.<br/>
/// Uses ARP
/// </summary>
/// <param name="ipAddress">The remote IP address.</param>
/// <param name="recheckNo">Number of retries more</param>
/// <remarks>
/// To make sure it's not empty pings before if necessary<br/>
/// &#9888; ONLY WORKS ON LAN
/// </remarks>
/// <returns>The remote machine's MAC address.</returns>
public static PhysicalAddress GetMacAddress(IPAddress ipAddress, int recheckNo = 2)
{
    const int MacByteLength = 6;
    int length = MacByteLength;
    var macBytes = new byte[MacByteLength];
    SendARP(BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0), 0, macBytes, ref length);

    bool hasAllZeroes = macBytes.All(singleByte => singleByte == 0);

    if (hasAllZeroes && recheckNo>0)
    {
        recheckNo--;
        if (CheckPing(ipAddress, 3, 5))
        {
            Task.Delay(1000).ConfigureAwait(false);
            return GetMacAddress(ipAddress, recheckNo);
        }            
    }

    if (hasAllZeroes)
        return null;

    return new PhysicalAddress(macBytes);
}

// http://www.codeproject.com/KB/IP/host_info_within_network.aspx
/// <summary>
/// Windows SendARP using "iphlpapi.dll"
/// </summary>
/// <returns></returns>
[System.Runtime.InteropServices.DllImport("iphlpapi.dll", ExactSpelling = true)]
static extern int SendARP(int DestIP, int SrcIP, byte[] pMacAddr, ref int PhyAddrLen);

/// <summary>
/// Basic Ping request. No Exception return, on error returns false
/// </summary>
/// <param name="ipOrString">IPAddress or string</param>
/// <param name="sec">Timeout in Seconds</param>
/// <param name="ttl">Time to Live</param>
public static bool CheckPing(object ipOrString, int sec = 3, int ttl = 10)
{

    var rep = GetPingReply(ipOrString, sec, ttl);

    return rep != null ? rep.Status == IPStatus.Success : false;

}

/// <summary>
/// Get Ping Reply
/// </summary>
/// <param name="ipOrString">IPAddress or string</param>
/// <param name="sec">Timeout in Seconds</param>
/// <param name="ttl">Time to Live</param>
/// <returns></returns>
public static PingReply GetPingReply(object ipOrString, int sec = 3, int ttl = 10)
{
    int timeout = sec * 1000;

    using (Ping pingSender = new Ping())
    {
        PingOptions options = new PingOptions(ttl, true);

        if (ipOrString is string host)
        {
            return pingSender.Send(host, timeout, new byte[32], options);
        }
        if (ipOrString is IPAddress ip)
        {
            return pingSender.Send(ip, timeout, new byte[32], options);
        }
        throw new ArgumentException("GetPingReply: Argument 'ipOrString' must be a 'IPAddress' or a 'string'");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.