首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >获取默认网关

获取默认网关
EN

Stack Overflow用户
提问于 2012-11-30 05:15:51
回答 9查看 39K关注 0票数 27

我正在写一个程序,显示用户的IP地址,子网掩码和默认网关。我可以得到前两个,但对于最后一个,这是我发现的:

代码语言:javascript
复制
GatewayIPAddressInformationCollection gwc = 
    System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()[0].GetIPProperties().GatewayAddresses;

当然,这将返回一个GatewayIPAddressInformation集合。那么,如果一台计算机有多个网关,我如何确定哪个是默认网关?

在实践中,我曾经见过这个集合只包含一个条目,但由于它是作为一个集合实现的,因此一些计算机包含多个网关是有道理的,这些网关都没有标记为“默认”。那么,有没有办法确定默认值,或者这一切都只是猜测?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2012-11-30 05:26:52

它可能是第一个启用的网络接口的第一个有效且启用的网关地址:

代码语言:javascript
复制
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,其他所有内容都发送到您的路由器)。

代码语言:javascript
复制
[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类中,并在适当的情况下使用:如果您有,或者在脑海中还没有目的地地址。

票数 44
EN

Stack Overflow用户

发布于 2015-04-07 22:34:51

traceroute命令返回的第一个IP地址将是网关.You可以利用这一事实获取网关。tracerout的一个很好的实现可以在这里找到:TraceRoute and Ping in C#

票数 4
EN

Stack Overflow用户

发布于 2015-02-17 00:35:30

我知道这是一个稍微老一点的问题,但是,我刚刚发现需要检索本地网关的IPV4地址。当涉及到我自己的系统时,公认的答案并不完全符合要求,所以我将其修改为suite,我相信其他人也可以使用这个解决方案。

由于我还没有足够的代表来发表评论,我不得不将此作为一个“问题”添加进来:

代码语言:javascript
复制
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;
    }
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13634868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档