Fre*_*oot 26 c# network-programming network-protocols
我正在编写一个程序,向用户显示他们的IP地址,子网掩码和默认网关.我可以得到前两个,但对于最后一个,这就是我出现的:
GatewayIPAddressInformationCollection gwc =
System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].GetIPProperties().GatewayAddresses;
Run Code Online (Sandbox Code Playgroud)
当然,这会返回一个集合GatewayIPAddressInformation.因此,如果计算机有多个网关,我如何确定哪个是默认网关?
在实践中,我只看到过这个集合包含一个条目,但由于它是作为集合实现的,因此有些计算机包含多个网关,其中没有一个被标记为"默认".那么有没有办法确定默认值还是只是猜测?
cae*_*say 38
它应该是第一个启用的网络接口的第一个有效和启用的网关地址:
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();
}
Run Code Online (Sandbox Code Playgroud)
我还添加了一些进一步评论的检查,这些检查已经被其他人指出是有用的.您可以检查AddressFamily一个区分IPv4和IPv6.如果您在0.0.0.0返回地址时遇到问题,可以使用后者.
也就是说,推荐的方法是使用它GetBestInterface来查找路由到特定IP地址的接口.如果您已经考虑了目标IP地址,那么最好使用它 - 所以我还包括以下示例:
[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;
}
Run Code Online (Sandbox Code Playgroud)