在。net中检查Internet连接的最快和最有效的方法是什么?


当前回答

private bool ping()
{
    System.Net.NetworkInformation.Ping pingSender = new System.Net.NetworkInformation.Ping();
    System.Net.NetworkInformation.PingReply reply = pingSender.Send(address);
    if (reply.Status == System.Net.NetworkInformation.IPStatus.Success)
    {                
        return true;
    }
    else
    {                
        return false;
    }
}

其他回答

尽量避免通过捕获异常来测试连接。因为我们真的预料到有时我们可能会失去网络连接。

 if (NetworkInterface.GetIsNetworkAvailable() &&
     new Ping().Send(new IPAddress(new byte[] { 8, 8, 8, 8 }),2000).Status == IPStatus.Success)
 //is online
 else
 //is offline

ping google.com会引入一个DNS解析依赖。ping 8.8.8.8很好,但谷歌离我很远。我所需要做的就是在互联网上ping离我最近的东西。

我可以使用Ping的TTL功能来Ping跳#1,然后跳#2,等等,直到我从一个可路由地址上的某个东西得到回复;如果该节点在一个可路由地址上,那么它就在因特网上。对于我们大多数人来说,跳点1将是我们的本地网关/路由器,跳点2将是光纤连接或其他设备的另一侧的第一个点。

这段代码对我有用,比这个线程中的其他一些建议反应更快,因为它是在互联网上ping离我最近的任何东西。


using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Threading.Tasks;
    
public static async Task<bool> IsConnectedToInternetAsync()
{
    const int maxHops = 30;
    const string someFarAwayIpAddress = "8.8.8.8";
    
    // Keep pinging further along the line from here to google 
    // until we find a response that is from a routable address
    for (int ttl = 1; ttl <= maxHops; ttl++)
    {
        var options = new PingOptions(ttl, true);
        byte[] buffer = new byte[32];
        PingReply reply;
        try
        {
            using (var pinger = new Ping())
            {
                reply = await pinger.SendPingAsync(someFarAwayIpAddress, 10000, buffer, options);
            }
        }
        catch (PingException pingex)
        {
            Debug.Print($"Ping exception (probably due to no network connection or recent change in network conditions), hence not connected to internet. Message: {pingex.Message}");
            return false;
        }
    
        string address = reply.Address?.ToString() ?? null;
        Debug.Print($"Hop #{ttl} is {address}, {reply.Status}");
    
        if (reply.Status != IPStatus.TtlExpired && reply.Status != IPStatus.Success)
        {
            Debug.Print($"Hop #{ttl} is {reply.Status}, hence we are not connected.");
            return false;
        }
    
        if (IsRoutableAddress(reply.Address))
        {
            Debug.Print("That's routable, so we must be connected to the internet.");
            return true;
        }
    }
    
    return false;
}
    
private static bool IsRoutableAddress(IPAddress addr)
{
    if (addr == null)
    {
        return false;
    }
    else if (addr.AddressFamily == AddressFamily.InterNetworkV6)
    {
        return !addr.IsIPv6LinkLocal && !addr.IsIPv6SiteLocal;
    }
    else // IPv4
    {
        byte[] bytes = addr.GetAddressBytes();
        if (bytes[0] == 10)
        {   // Class A network
            return false;
        }
        else if (bytes[0] == 172 && bytes[1] >= 16 && bytes[1] <= 31)
        {   // Class B network
            return false;
        }
        else if (bytes[0] == 192 && bytes[1] == 168)
        {   // Class C network
            return false;
        }
        else
        {   // None of the above, so must be routable
            return true;
        }
    }
}

而不是检查,只需执行操作(web请求,邮件,ftp等),并为请求失败做好准备,即使检查成功,您也必须这样做。

考虑以下几点:

1 - check, and it is OK
2 - start to perform action 
3 - network goes down
4 - action fails
5 - lot of good your check did

如果网络坏了,你的动作就会像ping一样迅速失败。

1 - start to perform action
2 - if the net is down(or goes down) the action will fail
public static bool CheckForInternetConnection(int timeoutMs = 10000, string url = null)
{
    try
    {
        url ??= CultureInfo.InstalledUICulture switch
        {
            { Name: var n } when n.StartsWith("fa") => // Iran
                "http://www.aparat.com",
            { Name: var n } when n.StartsWith("zh") => // China
                "http://www.baidu.com",
            _ =>
                "http://www.gstatic.com/generate_204",
        };

        var request = (HttpWebRequest)WebRequest.Create(url);
        request.KeepAlive = false;
        request.Timeout = timeoutMs;
        using (var response = (HttpWebResponse)request.GetResponse())
            return true;
    }
    catch
    {
        return false;
    }
}

如果你想在网络/连接发生变化时通知用户/采取行动。 使用NLM API:

https://msdn.microsoft.com/en-us/library/ee264321.aspx http://www.codeproject.com/Articles/34650/How-to-use-the-Windows-NLM-API-to-get-notified-of