C# 如何检查网络连接?

C# 如何检查网络连接?,c#,networking,C#,Networking,确定是否有可用网络连接的最佳方法是什么?您可以使用以下方法在.NET 2.0中检查网络连接: 要监视IP地址的更改或网络可用性的更改,请使用类中的事件: 标记的答案是100%好,但是,在某些情况下,标准方法被虚拟卡(虚拟盒,…)愚弄。根据网络接口的速度(串口、调制解调器等),通常也需要丢弃一些网络接口 下面是一段检查这些情况的代码: /// <summary> /// Indicates whether any network connection is availa

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

您可以使用以下方法在.NET 2.0中检查网络连接:

要监视IP地址的更改或网络可用性的更改,请使用类中的事件:


标记的答案是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;
    }
//
///指示是否有任何网络连接可用
///过滤低于指定速度的连接以及虚拟网卡。
/// 
/// 
///如果网络连接可用,则为true;否则,错误。
/// 
公共静态bool IsNetworkAvailable()
{
返回IsNetworkAvailable(0);
}
/// 
///指示是否有任何网络连接可用。
///过滤低于指定速度的连接以及虚拟网卡。
/// 
///所需的最低速度。传递0将不会使用速度筛选连接。
/// 
///如果网络连接可用,则为true;否则,错误。
/// 
公共静态网络可用(长最小速度)
{
如果(!NetworkInterface.GetIsNetworkAvailable())
返回false;
foreach(NetworkInterface.GetAllNetworkInterfaces()中的NetworkInterface)
{
//由于标准原因而放弃
如果((ni.OperationalStatus!=OperationalStatus.Up)||
(ni.NetworkInterfaceType==NetworkInterfaceType.Loopback)||
(ni.NetworkInterfaceType==NetworkInterfaceType.Tunnel))
继续;
//这允许过滤调制解调器、串行等。
//在大多数情况下,我使用10000000作为最低速度
如果(ni.速度<最小速度)
继续;
//丢弃虚拟卡(虚拟盒、虚拟pc等)
if((ni.Description.IndexOf(“virtual”,StringComparison.OrdinalIgnoreCase)>=0)||
(ni.Name.IndexOf(“virtual”,StringComparison.OrdinalIgnoreCase)>=0))
继续;
//放弃“Microsoft环回适配器”,它将不会显示为NetworkInterfaceType.Loopback,而是显示为以太网卡。
if(ni.Description.Equals(“Microsoft环回适配器”,StringComparison.OrdinalIgnoreCase))
继续;
返回true;
}
返回false;
}

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

  • NCSI在www.msftncsi.com上执行DNS查找,然后请求。此文件是纯文本文件,仅包含文本“Microsoft NCSI”
  • NCSI向DNS.msftncsi.com发送DNS查找请求。此DNS地址应解析为131.107.255.255。如果地址不匹配,则假定internet连接无法正常工作

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

    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);
    

    这是否考虑到“有限可用性”?这在WPF中并不总是有效。有些笔记本电脑返回错误,有些返回真实这真的有效吗?我只是写了这句话,关掉了路由器,结果仍然是真的
    NetworkInterface.GetIsNetworkAvailable()
    在我的应用程序(.NET 4.5,Windows 10)中非常不可靠,尤其是在虚拟机中运行时。从
    NetworkAvailabilityChanged
    处理事件是可靠的。这是不可靠的。阅读此内容是正确的,值得进行多次投票-我发现在接受的答案中提到的NetworkAvailabilityChanged事件没有可靠地触发,这可能是由于此答案中提到的虚拟适配器+1用于虚拟机的附加检查。昨天刚碰到这个案子。但我仍然认为这不能处理“Hype-V”,因为他们的名字中没有“virtual”。@Herdo-是的,代码并不完美,我认为虚拟世界中不可能有任何完美的东西。但是你可以改进它。@SimonMourier你是对的。我只想指出,如果有人仍然返回true,如果没有连接-->这可能是一个问题:)@noelicus-在我目前从事的项目中,我已经实现了一个定期监视/轮询系统(简单的HTTP GET请求,因为我的目标是web服务器),当检测到服务器“关闭”时会引发事件(无法通过HTTP访问)或“向上”(再次访问)。在一般情况下,您可以定义“可靠”在您的案例中的含义,并实现类似的逻辑。这很好,但从技术上讲不是关于“网络”的可用性,而是更多的“我是否通过http连接到internet?”您可以拥有完美的网络连接,但不连接到internet,例如在独立lan上。有关NCSI的更多信息,请参阅:的可能副本
    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);