C# - 查找我机器的本地 IP 地址而不是 VM 的
Posted
技术标签:
【中文标题】C# - 查找我机器的本地 IP 地址而不是 VM 的【英文标题】:C# - Finding my machine's local IP Address and not the VM's 【发布时间】:2011-12-26 17:50:01 【问题描述】:我的机器上安装了 VirtualBox VM,因此出现了一个以太网适配器。我正在通过以下方式枚举我机器的 IP 地址列表:
public string GetLocalIpAddress()
try
string strHostName = Dns.GetHostName();
// Then using host name, get the IP address list..
IPHostEntry ipEntry = Dns.GetHostEntry(strHostName);
foreach (IPAddress ip in ipEntry.AddressList)
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
return string.Format("(0)", ip.ToString());
catch(Exception e)
Global.ApplicationLog.AddApplicationLog(EnumAppEventTypes.SYSTEM_ERROR, e.ToString());
return "";
我的问题是虚拟机的以太网适配器也捕捉到了这种情况:
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
有没有办法找出我机器的本地 IP 地址而忽略我的虚拟机?
【问题讨论】:
【参考方案1】:我正在完善 Andrej Arh 的答案,因为 GatewayAddresses 报告的 IP 地址也可以是“0.0.0.0”,而不仅仅是 null:
public static string GetPhysicalIPAdress()
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
var addr = ni.GetIPProperties().GatewayAddresses.FirstOrDefault();
if (addr != null && !addr.Address.ToString().Equals("0.0.0.0"))
if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
return ip.Address.ToString();
return String.Empty;
【讨论】:
如果没有网关但地址仍然是物理地址,这不起作用。【参考方案2】:使用 WMI 并检查物理设备的 ConnectorPresent 属性。
public static string GetPhysicalIPAdress()
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
if (ConnectorPresent(ni))
if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
return ip.Address.ToString();
return string.Empty;
private static bool ConnectorPresent(NetworkInterface ni)
ManagementScope scope = new ManagementScope(@"\\localhost\root\StandardCimv2");
ObjectQuery query = new ObjectQuery(String.Format(
@"SELECT * FROM MSFT_NetAdapter WHERE ConnectorPresent = True AND DeviceID = '0'", ni.Id));
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection result = searcher.Get();
return result.Count > 0;
【讨论】:
这对我来说只需要一个调整:我还检查了 ni.OperationalStatus == OperationalStatus.Up。如果没有额外的检查,它会返回实际上已关闭的接口。【参考方案3】:只有一种选择。虚拟机 IP 没有默认网关,所以排除所有没有默认网关的 IP。
foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
var addr = ni.GetIPProperties().GatewayAddresses.FirstOrDefault();
if (addr != null)
if (ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet)
Console.WriteLine(ni.Name);
foreach (UnicastIPAddressInformation ip in ni.GetIPProperties().UnicastAddresses)
if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
Console.WriteLine(ip.Address.ToString());
【讨论】:
【参考方案4】:您可以忽略以太网适配器的名称。由于 VM 以太网适配器由有效的 NIC 驱动程序表示,因此从操作系统的角度来看,它完全等同于您机器的物理 NIC。
【讨论】:
不幸的是,IPAddress 类似乎没有保留以太网适配器的名称,因此我无法使用该方法消除 VM 以太网适配器。 是的,您可能需要使用 NetworkInterface.GetAllNetworkInterfaces() 方法更改您的方法。它将返回所有接口,然后您可以枚举每个接口的所有可用 IP 地址。 您好 pennanth,我似乎在 NetworkInterface 类中找不到任何显示 IP 地址的成员变量。如果我错了,也请纠正我,但是通过使用 NetworkInterface 类的名称,您可以通过重命名以太网适配器名称来破坏它?我正在寻找比这更可靠的解决方案 嗯,没有保证可以将虚拟网卡与物理网卡区分开来。他们都由真正的司机代表,并且没有任何徽章说“我是虚拟的”。因此,隔离 NIC 的唯一方法是要求用户标记虚拟 NIC(然后您可以使用 NIC 的 GUID 区分彼此)。 这不是我一直在寻找的理想解决方案,但根据您的说法,没有明确的实施方法。会将您的答案标记为已接受。感谢您提供信息。以上是关于C# - 查找我机器的本地 IP 地址而不是 VM 的的主要内容,如果未能解决你的问题,请参考以下文章