【问题标题】:How do I check for a network connection?如何检查网络连接?
【发布时间】:2010-10-05 22:36:18
【问题描述】:

确定是否有可用网络连接的最佳方法是什么?

【问题讨论】:

标签: c# networking


【解决方案1】:

标记的答案是 100% 没问题,但是,在某些情况下,标准方法会被虚拟卡片(虚拟盒子,...)所欺骗。根据速度(串行端口、调制解调器等)丢弃一些网络接口通常也是可取的。

这是检查这些情况的一段代码:

    /// <summary>
    /// Indicates whether any network connection is available
    /// Filter connections below a specified speed, as well as virtual network cards.
    /// </summary>
    /// <returns>
    ///     <c>true</c> if a network connection is available; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNetworkAvailable()
    {
        return IsNetworkAvailable(0);
    }

    /// <summary>
    /// Indicates whether any network connection is available.
    /// Filter connections below a specified speed, as well as virtual network cards.
    /// </summary>
    /// <param name="minimumSpeed">The minimum speed required. Passing 0 will not filter connection using speed.</param>
    /// <returns>
    ///     <c>true</c> if a network connection is available; otherwise, <c>false</c>.
    /// </returns>
    public static bool IsNetworkAvailable(long minimumSpeed)
    {
        if (!NetworkInterface.GetIsNetworkAvailable())
            return false;

        foreach (NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces())
        {
            // discard because of standard reasons
            if ((ni.OperationalStatus != OperationalStatus.Up) ||
                (ni.NetworkInterfaceType == NetworkInterfaceType.Loopback) ||
                (ni.NetworkInterfaceType == NetworkInterfaceType.Tunnel))
                continue;

            // this allow to filter modems, serial, etc.
            // I use 10000000 as a minimum speed for most cases
            if (ni.Speed < minimumSpeed)
                continue;

            // discard virtual cards (virtual box, virtual pc, etc.)
            if ((ni.Description.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0) ||
                (ni.Name.IndexOf("virtual", StringComparison.OrdinalIgnoreCase) >= 0))
                continue;

            // discard "Microsoft Loopback Adapter", it will not show as NetworkInterfaceType.Loopback but as Ethernet Card.
            if (ni.Description.Equals("Microsoft Loopback Adapter", StringComparison.OrdinalIgnoreCase))
                continue;

            return true;
        }
        return false;
    }

【讨论】:

  • 这是正确的,值得很多赞成 - 我发现接受的答案中提到的 NetworkAvailabilityChanged 事件没有被可靠地触发,这可能是由这个答案中提到的虚拟适配器引起的
  • +1 用于额外检查虚拟机。昨天刚碰到这个案子。但我仍然认为这不能处理“Hype-V”,因为他们的名字中没有“虚拟”。
  • @Herdo - 是的,代码并不完美,而且我认为在虚拟世界中不可能有任何完美的东西。但你可以改进它。
  • @SimonMourier 你是对的。只是想指出,如果有人仍然返回 true,如果没有连接 --> 这可能是一个问题 :)
  • @noelicus - 在我一直从事的项目中,我已经实现了一个定期监控/轮询系统(简单的 HTTP GET 请求,因为我的目标是 Web 服务器),它在服务器运行时引发事件检测为“down”(无法通过 HTTP 访问)或“up”(可再次访问)。在一般情况下,您可以在您的情况下定义“可靠”的含义,并实现类似的逻辑。
【解决方案2】:

您可以使用GetIsNetworkAvailable() 在 .NET 2.0 中检查网络连接:

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

要监控 IP 地址的变化或网络可用性的变化,请使用 NetworkChange 类中的事件:

System.Net.NetworkInformation.NetworkChange.NetworkAvailabilityChanged
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged

【讨论】:

  • 这能解决“有限的可用性”问题吗?
  • 这在 WPF 中并不总是有效。有些笔记本电脑返回 false,有些返回 true
  • 这真的有效吗?我刚刚写了这行,然后关闭了我的路由器,仍然返回 true!
  • NetworkInterface.GetIsNetworkAvailable() 在我的应用程序(.NET 4.5、Windows 10)中非常不可靠,尤其是在虚拟机中运行时。处理来自NetworkAvailabilityChanged 的事件是可靠的。
【解决方案3】:

Microsoft windows vista 和 7 使用 NCSI(网络连接状态指示器)技术:

  1. NCSI 在 www.msftncsi.com 上执行 DNS 查找,然后请求 http://www.msftncsi.com/ncsi.txt。此文件是纯文本文件,仅包含文本“Microsoft NCSI”。
  2. NCSI 为 dns.msftncsi.com 发送 DNS 查找请求。此 DNS 地址应解析为 131.107.255.255。如果地址不匹配,则认为互联网连接不正常。

【讨论】:

  • 这很好,但从技术上讲不是关于“网络”的可用性,而是更多关于“我通过 http 连接互联网吗?”您可以拥有完美的网络连接,但无法连接到互联网,例如在独立局域网上。有关更多信息,请参阅 NCSI:technet.microsoft.com/en-us/library/cc766017.aspx
【解决方案4】:

调用此方法检查网络连接。

public static bool IsConnectedToInternet()
        {
            bool returnValue = false;
            try
            {

                int Desc;
                returnValue = Utility.InternetGetConnectedState(out Desc, 0);
            }
            catch
            {
                returnValue = false;
            }
            return returnValue;
        }

把它放在代码行下面。

[DllImport("wininet.dll")]
        public extern static bool InternetGetConnectedState(out int Description, int ReservedValue);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多