确定互联网连接是否可用

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

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

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

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

我的解决方法是每500ms轮询一次NetworkInterface.GetAllNetworkInterfaces(),并在网络适配器的状态发生变化时抛出我自己的事件。

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

我尝试了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 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); } } } } 

使用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"); } } 

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

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

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

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

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

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

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

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

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