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


当前回答

以下是它在Android中的实现方式。

作为概念的证明,我将这段代码翻译成c#:

var request = (HttpWebRequest)WebRequest.Create("http://g.cn/generate_204");
request.UserAgent = "Android";
request.KeepAlive = false;
request.Timeout = 1500;

using (var response = (HttpWebResponse)request.GetResponse())
{
    if (response.ContentLength == 0 && response.StatusCode == HttpStatusCode.NoContent)
    {
        //Connection to internet available
    }
    else
    {
        //Connection to internet not available
    }
}

其他回答

我不认为这是不可能的,只是不简单。

我已经建立了这样的东西,是的,它并不完美,但第一步是必不可少的:检查是否有任何网络连接。Windows Api做得不好,为什么不做得更好呢?

bool NetworkIsAvailable()
{
    var all = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    foreach (var item in all)
    {
        if (item.NetworkInterfaceType == NetworkInterfaceType.Loopback)
            continue;
        if (item.Name.ToLower().Contains("virtual") || item.Description.ToLower().Contains("virtual"))
            continue; //Exclude virtual networks set up by VMWare and others
        if (item.OperationalStatus == OperationalStatus.Up)
        {
            return true;
        }
    }

    return false;
}

这非常简单,但它确实有助于提高检查的质量,特别是当您想检查各种代理配置时。

So:

检查是否有网络连接(让这真的很好,甚至可以在出现误报时将日志发送给开发人员,以改进NetworkIsAvailable功能) HTTP平 (循环代理配置,在每个代理上使用HTTP ping)

根据@ChaosPandion的回答,为了尽可能确保结果是正确的,你可以像其他人指出的那样,包括多个大网站。但是,这应该异步完成,以避免太长的等待时间。此外,WebRequest、HttpWebRequest和HttpWebResponse类现在已经过时,应该被HttpClient取代。以下示例考虑了上述因素:

public static async Task<bool> CheckForInternetConnection(TimeSpan? timeoutMs = null, List<string> urls = null)
{
    if (timeoutMs == null)
    {
        timeoutMs = TimeSpan.FromSeconds(10);
    }

    var culture = CultureInfo.InstalledUICulture;
    if (urls == null)
    {
        urls = new List<string>();

        if (culture.Name.StartsWith("fa"))      // Iran
            urls.Add("http://www.aparat.com");
        else if (culture.Name.StartsWith("zh")) // China
            urls.Add("http://www.baidu.com");
        else
        {
            urls.Add("https://www.apple.com/");
            urls.Add("https://www.gstatic.com/generate_204");
        }
    }

    var client = new HttpClient();
    client.Timeout = (TimeSpan)timeoutMs;
    List<Task<string>> tasks = new List<Task<string>>();
    int unresponsiveUrlCount = 0;

    foreach (var url in urls)
    {   
        tasks.Add(client.GetStringAsync(url));             
    }

    Task aggregationTask = null;
    try
    {
        aggregationTask = Task.WhenAll(tasks);
        await aggregationTask;
    }
    catch (Exception)
    {  
        if (aggregationTask?.Exception?.InnerExceptions != null && aggregationTask.Exception.InnerExceptions.Any())
        {
            foreach (var innerEx in aggregationTask.Exception.InnerExceptions)
            {
                unresponsiveUrlCount++;
            }
        }      
    }

    return unresponsiveUrlCount < urls.Count;
}

该方法检查列表中的所有url,如果它们都不可访问,则返回false。我已经添加了苹果的url,因为在我的情况下,它加载相当快,但它可以替换为任何url。

我个人觉得Anton和moffeltje的答案最好,但我增加了一个检查,排除VMWare和其他公司设置的虚拟网络。

public static bool IsAvailableNetworkActive()
{
    // only recognizes changes related to Internet adapters
    if (!System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()) return false;

    // however, this will include all adapters -- filter by opstatus and activity
    NetworkInterface[] interfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
    return (from face in interfaces
            where face.OperationalStatus == OperationalStatus.Up
            where (face.NetworkInterfaceType != NetworkInterfaceType.Tunnel) && (face.NetworkInterfaceType != NetworkInterfaceType.Loopback)
            where (!(face.Name.ToLower().Contains("virtual") || face.Description.ToLower().Contains("virtual")))
            select face.GetIPv4Statistics()).Any(statistics => (statistics.BytesReceived > 0) && (statistics.BytesSent > 0));
}

我有三个网络连接测试。

参考系统。Net和system.net.socket 增加以下测试功能:

测试1

public bool IsOnlineTest1()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

测试2

public bool IsOnlineTest2()
{
    try
    {
        IPHostEntry dummy = Dns.GetHostEntry("https://www.google.com");
        return true;
    }
    catch (SocketException ex)
    {
        return false;
    }
}

测试3

public bool IsOnlineTest3()
{
    System.Net.WebRequest req = System.Net.WebRequest.Create("https://www.google.com");
    System.Net.WebResponse resp = default(System.Net.WebResponse);
    try
    {
        resp = req.GetResponse();
        resp.Close();
        req = null;
        return true;
    }
    catch (Exception ex)
    {
        req = null;
        return false;
    }
}

执行测试

如果您创建了一个名为CheckList的字符串和布尔字典,则可以将每个测试的结果添加到CheckList中。

现在,递归遍历每个KeyValuePair使用for…每一个循环。

如果检查表的值为true,则您知道有Internet连接。

而不是检查,只需执行操作(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