c# 扫描局域网IP和MAC地址,计算机名
时间: 2025-04-04 18:05:14 浏览: 44
### 如何使用C#扫描局域网中的IP、MAC地址和计算机名称
要实现通过C#程序来扫描局域网内的设备并获取其IP地址、MAC地址以及主机名,可以采用以下方法:
#### 获取网络适配器信息
利用 `System.Net.NetworkInformation` 命名空间下的类库可以帮助我们访问本地网络接口的信息。这些信息包括 MAC 地址和其他配置细节。
```csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
public class NetworkScanner
{
public static void Main()
{
List<string> activeHosts = PingNetwork("192.168.1", 1, 254);
foreach (var host in activeHosts)
{
Console.WriteLine($"Active Host: {host}");
try
{
IPHostEntry entry = Dns.GetHostEntry(host);
string computerName = entry.HostName.Split('.')[0];
PhysicalAddress macAddress = GetMacAddress(entry.AddressList.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork));
Console.WriteLine($"\tComputer Name: {computerName}");
Console.WriteLine($"\tMAC Address: {macAddress?.ToString() ?? "N/A"}");
}
catch (Exception ex)
{
Console.WriteLine($"\tError retrieving details for {host}: {ex.Message}");
}
}
}
private static List<string> PingNetwork(string subnet, int startRange, int endRange)
{
var activeHosts = new List<string>();
Parallel.For(startRange, endRange + 1, i =>
{
string ipAddress = $"{subnet}.{i}";
bool isReachable = IsPingSuccessful(ipAddress);
if (isReachable)
{
lock (activeHosts)
{
activeHosts.Add(ipAddress);
}
}
});
return activeHosts;
}
private static bool IsPingSuccessful(string ipAddress)
{
using (Ping pingSender = new Ping())
{
try
{
PingReply reply = pingSender.Send(IPAddress.Parse(ipAddress), 100); // Timeout set to 100ms.
return reply.Status == IPStatus.Success;
}
catch
{
return false;
}
}
}
private static PhysicalAddress GetMacAddress(IPAddress ipAddress)
{
if (ipAddress != null && !string.IsNullOrEmpty(ipAddress.ToString()))
{
try
{
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.IP))
{
byte[] buffer = new byte[PhysicalAddress.MaxByteLength];
IAsyncResult result = socket.BeginConnect(new IPEndPoint(ipAddress, 137), null, null);
if (!result.AsyncWaitHandle.WaitOne(100)) // Wait up to 100 milliseconds.
throw new Exception();
socket.EndConnect(result);
foreach (NetworkInterface adapter in NetworkInterface.GetAllNetworkInterfaces())
{
if (adapter.OperationalStatus == OperationalStatus.Up &&
adapter.Supports(NetworkInterfaceComponent.IPv4))
{
UnicastIPAddressInformationCollection uniCastInfoColl =
adapter.GetIPProperties().UnicastAddresses;
foreach (UnicastIPAddressInformation unicastAddr in uniCastInfoColl)
{
if (unicastAddr.Address.Equals(ipAddress))
return adapter.GetPhysicalAddress();
}
}
}
}
}
catch
{
return null;
}
}
return null;
}
}
```
上述代码实现了以下几个功能:
- **Ping 扫描**:遍历指定子网范围内的所有可能的 IP 地址,并尝试发送 ICMP 请求以检测目标机器是否在线[^1]。
- **DNS 查询**:对于每一个响应成功的 IP 地址,调用 `Dns.GetHostEntry()` 方法解析对应的主机名。
- **MAC 地址提取**:通过建立临时套接字连接到目标端口(如 NetBIOS 的 137 端口),随后匹配当前活动网络接口上的物理地址与目标 IP 关联起来。
需要注意的是,在实际部署此应用程序之前,请确保已获得适当权限许可,因为某些操作可能会受到防火墙或其他安全机制的影响。
#### 配置最大并发请求数量
如果计划扩展该工具支持更多复杂场景,则应考虑调整 .NET 应用默认的最大外部连接数限制。可以通过修改应用配置文件中的 `<system.net>` 节点完成设置[^2]。
```xml
<configuration>
<system.net>
<connectionManagement>
<add address="*" maxconnection="100"/>
</connectionManagement>
</system.net>
</configuration>
```
这样做的目的是提高多线程环境下发起大量异步任务时的整体性能表现。
---
阅读全文
相关推荐

















