我知道我不是第一个提出这个问题的人:我如何知道我的申请是否在线? 我找到了这篇文章:StackOverflow。 我想用C#和.NET 3.5来做。
建议定期ping资源。我对这个建议不太满意。我宁愿检测网络更改,然后ping我的服务以检查它是否在线。
.NET为此提供了两个事件: NetworkChange.NetworkAvailabilityChanged NetworkChange.NetworkAddressChanged
第一个事件听起来不错,但只有当最后一个在线的网卡脱机时才会触发。我有几个虚拟网卡已经由VMWare安装,并且总是在线。 第二个事件有效,但在插入网络电缆和事件之间,通常有5秒的等待时间。 当我拔下电缆时,Windows托盘图标会或多或少立即作出反应。 像这个托盘图标一样快的最佳方法是什么?
我的解决方法是投票 NetworkInterface.GetAllNetworkInterfaces() 每隔500毫秒,如果网络适配器的状态发生变化,则抛出我自己的事件。
必须有更好的解决方案:)
答案 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但无法获得响应。如何在发生异常时正常处理异常?