确定互联网连接是否可用

时间:2022-09-24 23:53:11

I know that I am not the first to ask the question: How do I find out if my application is online or not? I found this post: *. I want to do it with C# and .NET 3.5.

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

The recommendation is to ping the resource regularly. I am not very happy with that advice. I would rather detect a network change and THEN ping my service to check if it is online.

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

.NET provides two events for this purpose: NetworkChange.NetworkAvailabilityChanged NetworkChange.NetworkAddressChanged

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

The first event sounds good but it is fired only if the last network card which is online goes offline. I have several virtual network cards which have been installed by VMWare and those are always online. The second event works but between plugging the network cable and the event, there are often 5 seconds wait time. The Windows tray icon reacts more or less immediately when I am unplugging the cable. What is the best way to be as fast as this tray icon?

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

My workaround would be to poll NetworkInterface.GetAllNetworkInterfaces() every 500ms and to throw my own event in case that the status of a network adapter changed.

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

There must be a better solution :)

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

8 个解决方案

#1


8  

I tried the link the Webleeuw suggested, but that code also needs between 4 and 10 seconds to notify me when I plug or unplug my cable. Now, I wanted to know if it just my computer or installation and I wrote my own Observer class which is based on NetworkInterface.GetAllNetworkInterfaces().

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

And: It works with lightning speed. My app reacts now as quickly as does the tray. The code is far from production code, it is just a quick hack. But this is what I will build upon now :)

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

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

#2


2  

Try this using NetworkChange class

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

#3


2  

People here already told it but there is a diference between network availability and internet availability.
You can have network availability between your network interface and local router but havent internet availability between your local router and your Internet Service Provider (ISP).
There is another problem that testing by ping will tell you about internet availability but not about what network interface is providing it, i think the only way is force ping throught one interface but it isnot possible on windows.

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

#4


0  

Pinging your resource regularly is the only option that will give you a notification if the service goes offline, as well as if the client goes offline. Potentially you want to handle both situations.

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

#5


0  

The windows tray icon is very likely connected to the network card drivers, i.e. below the operating system level which is why it can react so fast.

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

Since the network card is only one of many links between your client and the service that it accesses on the Internet, the only reliable way to detect whether or not the Internet is available is to poll some service out on the Internet, much the same way that ping does. In TCP/IP networking, this is known as a keepalive, and many protocols will have this built into them as an option.

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

#6


0  

About the pinging: depending on how you wish to interpret the results, pinging doesn't seem watertight to me. What if the target times out once in a while, while the connection remains alive? I have yet to see the server that never fails to respond to a ping.

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

Checking every X millis if the network interface is still online (NetworkInterface.OperationalStatus property) seems more reliable if you'd ask me.

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

EDIT: This article deals with network address events on a lower level than the System.Net.NetworkInformation.NetworkChange class, or so it seems. On my pc it works very fast, so hopefully you'll be able to use that solution.

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

#7


0  

You can use ping, but I would also build a simple call to return a "yes" if it is online. That way you do know if the server is up and that it is running your code. Also I would only call or ping when a network resource is needed and not continually.

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

#8


0  

Doing a ping is definitely not the cleanest option, especially if it is a web server. Some hosts will disable response to ICMP traffic, so you may ping but not get a response. How about just handling the exception gracefully when it occurs?

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

#1


8  

I tried the link the Webleeuw suggested, but that code also needs between 4 and 10 seconds to notify me when I plug or unplug my cable. Now, I wanted to know if it just my computer or installation and I wrote my own Observer class which is based on NetworkInterface.GetAllNetworkInterfaces().

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

And: It works with lightning speed. My app reacts now as quickly as does the tray. The code is far from production code, it is just a quick hack. But this is what I will build upon now :)

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

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

#2


2  

Try this using NetworkChange class

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

#3


2  

People here already told it but there is a diference between network availability and internet availability.
You can have network availability between your network interface and local router but havent internet availability between your local router and your Internet Service Provider (ISP).
There is another problem that testing by ping will tell you about internet availability but not about what network interface is providing it, i think the only way is force ping throught one interface but it isnot possible on windows.

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

#4


0  

Pinging your resource regularly is the only option that will give you a notification if the service goes offline, as well as if the client goes offline. Potentially you want to handle both situations.

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

#5


0  

The windows tray icon is very likely connected to the network card drivers, i.e. below the operating system level which is why it can react so fast.

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

Since the network card is only one of many links between your client and the service that it accesses on the Internet, the only reliable way to detect whether or not the Internet is available is to poll some service out on the Internet, much the same way that ping does. In TCP/IP networking, this is known as a keepalive, and many protocols will have this built into them as an option.

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

#6


0  

About the pinging: depending on how you wish to interpret the results, pinging doesn't seem watertight to me. What if the target times out once in a while, while the connection remains alive? I have yet to see the server that never fails to respond to a ping.

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

Checking every X millis if the network interface is still online (NetworkInterface.OperationalStatus property) seems more reliable if you'd ask me.

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

EDIT: This article deals with network address events on a lower level than the System.Net.NetworkInformation.NetworkChange class, or so it seems. On my pc it works very fast, so hopefully you'll be able to use that solution.

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

#7


0  

You can use ping, but I would also build a simple call to return a "yes" if it is online. That way you do know if the server is up and that it is running your code. Also I would only call or ping when a network resource is needed and not continually.

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

#8


0  

Doing a ping is definitely not the cleanest option, especially if it is a web server. Some hosts will disable response to ICMP traffic, so you may ping but not get a response. How about just handling the exception gracefully when it occurs?

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