确定互联网连接是否可用

时间:2009-12-07 12:54:27

标签: c# .net networking

我知道我不是第一个提出这个问题的人:我如何知道我的申请是否在线? 我找到了这篇文章:StackOverflow。 我想用C#和.NET 3.5来做。

建议定期ping资源。我对这个建议不太满意。我宁愿检测网络更改,然后ping我的服务以检查它是否在线。

.NET为此提供了两个事件: NetworkChange.NetworkAvailabilityChanged NetworkChange.NetworkAddressChanged

第一个事件听起来不错,但只有当最后一个在线的网卡脱机时才会触发。我有几个虚拟网卡已经由VMWare安装,并且总是在线。 第二个事件有效,但在插入网络电缆和事件之间,通常有5秒的等待时间。 当我拔下电缆时,Windows托盘图标会或多或少立即作出反应。 像这个托盘图标一样快的最佳方法是什么?

我的解决方法是投票 NetworkInterface.GetAllNetworkInterfaces() 每隔500毫秒,如果网络适配器的状态发生变化,则抛出我自己的事件。

必须有更好的解决方案:)

8 个答案:

答案 0 :(得分:8)

我尝试了Webleeuw建议的链接,但是当我插上或拔掉电缆时,该代码还需要4到10秒才能通知我。 现在,我想知道它是否仅仅是我的计算机或安装,我编写了自己的Observer类,它基于NetworkInterface.GetAllNetworkInterfaces()。

并且:它以闪电般的速度运行。我的应用程序现在和托盘一样快。 代码远离生产代码,它只是一个快速的黑客。但这就是我现在要建立的:)

using System;
using System.Net.NetworkInformation;
using Timer=System.Threading.Timer;

namespace NetworkCheckApp
{
public class NetworkStatusObserver
{
    public event EventHandler<EventArgs> NetworkChanged;

    private NetworkInterface[] oldInterfaces;
    private Timer timer;

    public void Start()
    {
        timer = new Timer(UpdateNetworkStatus, null, new TimeSpan(0, 0, 0, 0, 500), new TimeSpan(0, 0, 0, 0, 500));

        oldInterfaces = NetworkInterface.GetAllNetworkInterfaces();
    }

    private void UpdateNetworkStatus(object o)
    {
        var newInterfaces = NetworkInterface.GetAllNetworkInterfaces();
        bool hasChanges = false;
        if (newInterfaces.Length != oldInterfaces.Length)
        {
            hasChanges = true;
        }
        if (!hasChanges)
        {
            for (int i = 0; i < oldInterfaces.Length; i++)
            {
                if (oldInterfaces[i].Name != newInterfaces[i].Name || oldInterfaces[i].OperationalStatus != newInterfaces[i].OperationalStatus)
                {
                    hasChanges = true;
                    break;
                }
            }
        }

        oldInterfaces = newInterfaces;

        if (hasChanges)
        {
            RaiseNetworkChanged();
        }
    }

    private void RaiseNetworkChanged()
    {
        if (NetworkChanged != null)
        {
            NetworkChanged.Invoke(this, null);
        }
    }
}
}

答案 1 :(得分:2)

使用 NetworkChange

尝试此操作
using System.Net.NetworkInformation

private void Form5_Load(object sender, EventArgs e)
{
    NetworkChange.NetworkAvailabilityChanged += new NetworkAvailabilityChangedEventHandler(NetworkChange_NetworkAvailabilityChanged);
}

private void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
{
    if (e.IsAvailable)
    {
        MessageBox.Show("Available");
    }
    else
    {
        MessageBox.Show("Not available");
    }
}

答案 2 :(得分:2)

这里的人已经告诉过它,但网络可用性和互联网可用性之间存在差异 您可以在网络接口和本地路由器之间保持网络可用性,但在本地路由器和Internet服务提供商(ISP)之间没有互联网可用性。 还有另外一个问题,通过ping测试会告诉你有关互联网可用性的信息,而不是关于网络接口提供它的情况,我认为唯一的方法是强制ping通过一个接口但是在Windows上是不可能的。

答案 3 :(得分:0)

定期ping资源是唯一可以在服务脱机时以及客户端脱机时通知您的选项。您可能希望处理这两种情况。

答案 4 :(得分:0)

Windows托盘图标很可能连接到网卡驱动程序,即低于操作系统级别,这就是它可以如此快速地做出反应的原因。

由于网卡只是客户端与其在Internet上访问的服务之间的众多链接之一,因此检测Internet是否可用的唯一可靠方法是在Internet上轮询某些服务。与ping的方式相同。在TCP / IP网络中,这被称为keepalive,许多协议将内置它们作为选项。

答案 5 :(得分:0)

关于ping:取决于你希望如何解释结果,ping对我来说似乎不是水密的。如果目标在一段时间内超时,而连接仍然存在,该怎么办?我还没有看到服务器永远无法响应ping。

如果您问我,网络接口是否仍然在线(NetworkInterface.OperationalStatus属性),检查每X毫秒是否更可靠。

编辑:This文章处理比System.Net.NetworkInformation.NetworkChange类更低级别的网络地址事件,或者看起来如此。在我的电脑上它工作得非常快,所以希望你能够使用这个解决方案。

答案 6 :(得分:0)

你可以使用ping,但我也会建立一个简单的调用,如果它在线,则返回“是”。这样您就可以知道服务器是否已启动并且是否正在运行您的代码。此外,我只会在需要网络资源时调用或ping,而不是连续调用。

答案 7 :(得分:0)

执行ping绝对不是最干净的选择,特别是如果它是Web服务器。某些主机将禁用对ICMP流量的响应,因此您可能会ping但无法获得响应。如何在发生异常时正常处理异常?