我正在写一个程序,显示用户的IP地址,子网掩码和默认网关。我可以得到前两个,但对于最后一个,这是我发现的:
GatewayIPAddressInformationCollection gwc =
System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].GetIPProperties().GatewayAddresses;
当然,这将返回一个GatewayIPAddressInformation
集合。那么,如果一台计算机有多个网关,我如何确定哪个是默认网关?
在实践中,我曾经见过这个集合只包含一个条目,但由于它是作为一个集合实现的,因此一些计算机包含多个网关是有道理的,这些网关都没有标记为“默认”。那么,有没有办法确定默认值,或者这一切都只是猜测?
发布于 2012-11-30 05:26:52
它可能是第一个启用的网络接口的第一个有效且启用的网关地址:
public static IPAddress GetDefaultGateway()
{
return NetworkInterface
.GetAllNetworkInterfaces()
.Where(n => n.OperationalStatus == OperationalStatus.Up)
.Where(n => n.NetworkInterfaceType != NetworkInterfaceType.Loopback)
.SelectMany(n => n.GetIPProperties()?.GatewayAddresses)
.Select(g => g?.Address)
.Where(a => a != null)
// .Where(a => a.AddressFamily == AddressFamily.InterNetwork)
// .Where(a => Array.FindIndex(a.GetAddressBytes(), b => b != 0) >= 0)
.FirstOrDefault();
}
我还添加了一些进一步的注释检查,这里的其他人已经指出这些检查很有用。您可以检查AddressFamily
来区分IPv4和IPv6。后者可用于过滤掉0.0.0.0地址。
上面的解决方案将为您提供一个有效/连接的接口,并且足以满足99%的情况。也就是说,如果您有多个可以路由流量的有效接口,并且您需要100%准确,则执行此操作的方法是使用GetBestInterface
查找用于路由到特定IP地址的接口。这还可以处理这样的情况,即您可能有一个特定的地址范围通过不同的适配器路由(例如,10.*.*.*
通过VPN,其他所有内容都发送到您的路由器)。
[DllImport("iphlpapi.dll", CharSet = CharSet.Auto)]
private static extern int GetBestInterface(UInt32 destAddr, out UInt32 bestIfIndex);
public static IPAddress GetGatewayForDestination(IPAddress destinationAddress)
{
UInt32 destaddr = BitConverter.ToUInt32(destinationAddress.GetAddressBytes(), 0);
uint interfaceIndex;
int result = GetBestInterface(destaddr, out interfaceIndex);
if (result != 0)
throw new Win32Exception(result);
foreach (var ni in NetworkInterface.GetAllNetworkInterfaces())
{
var niprops = ni.GetIPProperties();
if (niprops == null)
continue;
var gateway = niprops.GatewayAddresses?.FirstOrDefault()?.Address;
if (gateway == null)
continue;
if (ni.Supports(NetworkInterfaceComponent.IPv4))
{
var v4props = niprops.GetIPv4Properties();
if (v4props == null)
continue;
if (v4props.Index == interfaceIndex)
return gateway;
}
if (ni.Supports(NetworkInterfaceComponent.IPv6))
{
var v6props = niprops.GetIPv6Properties();
if (v6props == null)
continue;
if (v6props.Index == interfaceIndex)
return gateway;
}
}
return null;
}
这两个示例可以封装到一个helper类中,并在适当的情况下使用:如果您有,或者在脑海中还没有目的地地址。
发布于 2015-04-07 22:34:51
traceroute
命令返回的第一个IP地址将是网关.You可以利用这一事实获取网关。tracerout
的一个很好的实现可以在这里找到:TraceRoute and Ping in C#
发布于 2015-02-17 00:35:30
我知道这是一个稍微老一点的问题,但是,我刚刚发现需要检索本地网关的IPV4地址。当涉及到我自己的系统时,公认的答案并不完全符合要求,所以我将其修改为suite,我相信其他人也可以使用这个解决方案。
由于我还没有足够的代表来发表评论,我不得不将此作为一个“问题”添加进来:
public static IPAddress GetDefaultGateway()
{
IPAddress result = null;
var cards = NetworkInterface.GetAllNetworkInterfaces().ToList();
if (cards.Any())
{
foreach (var card in cards)
{
var props = card.GetIPProperties();
if (props == null)
continue;
var gateways = props.GatewayAddresses;
if (!gateways.Any())
continue;
var gateway =
gateways.FirstOrDefault(g => g.Address.AddressFamily.ToString() == "InterNetwork");
if (gateway == null)
continue;
result = gateway.Address;
break;
};
}
return result;
}
https://stackoverflow.com/questions/13634868
复制相似问题