C#检查互联网连接

23

请问我在运行C#程序时,有没有办法检查我的计算机是否连接到互联网。例如,如果互联网正常工作,我可以输出一个消息框,显示“Internet is available”。否则,我会输出一条消息,显示“Internet is unavailable”。

不使用库函数来检查网络是否可用(因为这不能检查互联网连接)

System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

或者不需要打开网页来查看它是否返回数据
using (WebClient client = new WebClient())
      htmlCode = client.DownloadString("http://google.com");

由于这两种方法都不满足我的需求。

2
关于ping呢?它比打开一个页面消耗更少的资源。 - elyashiv
6个回答

37
好的,以下是您需要翻译的内容:

稍微简短的版本:

public static bool CheckForInternetConnection()
{
    try
    {
        using (var client = new WebClient())
        using (var stream = client.OpenRead("http://www.google.com"))
        {
            return true;
        }
    }
    catch
    {
        return false;
    }
}

另一个选择是:

Ping myPing = new Ping();
String host = "google.com";
byte[] buffer = new byte[32];
int timeout = 1000;
PingOptions pingOptions = new PingOptions();
PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
if (reply.Status == IPStatus.Success) {
  // presumably online
}

您可以在此处找到更广泛的讨论。


2
使用“google.com”会花费更多时间,因为它需要被解析。相反,直接使用IP进行ping测试会更快。对Google公共DNS IP地址(8.8.8.88.8.4.4)进行ping测试对我来说效果很好。 - Mangesh
尽管你的代码在中国无法运行。 - Pritam
我正在结合两个选项。 - SamuraiJack

8
考虑以下代码片段...
Ping myPing = new Ping();
String host = "google.com";
byte[] buffer = new byte[32];
int timeout = 1000;
PingOptions pingOptions = new PingOptions();
PingReply reply = myPing.Send(host, timeout, buffer, pingOptions);
if (reply.Status == IPStatus.Success) 
{
  // presumably online
}

祝你好运!


需要被包裹在try块中,不同于其他回复。Ping.Send() 可能会抛出许多异常,其中可能包括DNS查找失败。 - Barton

2
刚刚编写了异步函数来完成这件事:
private void myPingCompletedCallback(object sender, PingCompletedEventArgs e)
{
    if (e.Cancelled)
        return;

    if (e.Error != null)
        return;

    if (e.Reply.Status == IPStatus.Success)
    {
        //ok connected to internet, do something...
    }
}

private void checkInternet()
{
    Ping myPing = new Ping();
    myPing.PingCompleted += new PingCompletedEventHandler(myPingCompletedCallback);
    try
    {
        myPing.SendAsync("google.com", 3000 /*3 secs timeout*/, new byte[32], new PingOptions(64, true));
    }
    catch
    {
    }
}

特别是对于包装在try块中,与其他回答不同。Ping.Send()可能会抛出许多异常,其中可能包括DNS查找失败。 - Barton

1

我的NetworkMonitor类现在提供了这个功能(基于其他答案):

    public bool IsInternetAvailable
    {
        get { return IsNetworkAvailable && _CanPingGoogle(); }
    }

    private static bool _CanPingGoogle()
    {
        const int timeout = 1000;
        const string host = "google.com";

        var ping = new Ping();
        var buffer = new byte[32];
        var pingOptions = new PingOptions();

        try {
            var reply = ping.Send(host, timeout, buffer, pingOptions);
            return (reply != null && reply.Status == IPStatus.Success);
        }
        catch (Exception) {
            return false;
        }
    }

0

这是我的方法:

  1. 检查网络连接是否可用,如果不可用,则无法连接到另一个主机。
  2. 检查是否可以连接到一些重要的主机。在某些情况下,使用备用方案以防该站点不可用。

    public static bool ConnectToInternet(int timeout_per_host_millis = 1000, string[] hosts_to_ping = null)
    {
        bool network_available = System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable();
    
        if (network_available)
        {
            string[] hosts = hosts_to_ping ?? new string[] { "www.google.com", "www.facebook.com" };
    
            Ping p = new Ping();
    
            foreach (string host in hosts)
            {
                try
                {
                    PingReply r = p.Send(host, timeout_per_host_millis);
    
                    if (r.Status == IPStatus.Success)
                        return true;
                }
                catch { }
            }
        }
    
        return false;
    }
    

注意事项:

  1. 在尝试连接时不要使用过多的主机,需要权衡所有ping操作所需的时间成本和成功的可能性。
  2. 如果我们将ping发送到稍后打算连接的某个主机(例如HTTP请求),返回的ping并不意味着我们已经连接到该特定主机。考虑一下如果该主机被阻止会发生什么情况。例如Facebook在伊朗、中国等地被屏蔽,那么该ISP是否会返回ping?
  3. DNS请求是不够的,因为它可能已被缓存。

-1
public static bool HasConnection()
{
    try
    {
        System.Net.IPHostEntry i = System.Net.Dns.GetHostEntry("www.google.com");
        return true;
    }
    catch
    {
        return false;
    }
}

3
实际上这可能会导致误报;计算机的DNS服务器可能已经缓存了“www.google.com”,但没有互联网连接。或者;计算机的DNS客户端服务也可能已经缓存它。 - Andrew Barber
获取目标IP地址是一回事,连接到它是另一回事! - Behzad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接