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


当前回答

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

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

其他回答

我有三个网络连接测试。

参考系统。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连接。

我已经看到了上面列出的所有选项,唯一可行的选项来检查互联网是否可用是“Ping”选项。 导入[DllImport("Wininet.dll")]和System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()或NetworkInterface类的任何其他变体都不能很好地检测网络的可用性。这些方法只检查网线是否插好。

“Ping选项”

if(Connection is available)返回true

if(连接不可用且网线已插入)返回false

if(网线未插入)抛出异常

的NetworkInterface

if(Internet可用)返回True

if(Internet不可用且网线已插入)返回True

if(Network Cable is Not plug in)返回false

[DllImport杂志》(“Wininet等”)。

if(Internet可用)返回True

if(Internet不可用且网线已插入)返回True

if(Network Cable is Not plug in)返回false

因此,在[DllImport("Wininet.dll")]和NetworkInterface的情况下,没有办法知道互联网连接是否可用。

根据@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。

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

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

我不同意有人说:“在执行任务之前检查连接有什么意义,因为检查之后连接可能会丢失”。 当然,我们作为开发人员承担的许多编程任务中都存在一定程度的不确定性,但将不确定性降低到可接受的水平是挑战的一部分。

我最近遇到了这个问题,使一个应用程序,其中包括一个映射功能,链接到一个在线瓷砖服务器。这一功能将在缺乏互联网连接时被禁用。

本页上的一些响应非常好,但确实导致了许多性能问题,例如挂起,主要是在没有连接的情况下。

以下是我最终使用的解决方案,在这些答案和我同事的帮助下:

         // Insert this where check is required, in my case program start
         ThreadPool.QueueUserWorkItem(CheckInternetConnectivity);
    }

    void CheckInternetConnectivity(object state)
    {
        if (System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable())
        {
            using (WebClient webClient = new WebClient())
            {
                webClient.CachePolicy = new System.Net.Cache.RequestCachePolicy(System.Net.Cache.RequestCacheLevel.BypassCache);
                webClient.Proxy = null;
                webClient.OpenReadCompleted += webClient_OpenReadCompleted;
                webClient.OpenReadAsync(new Uri("<url of choice here>"));
            }
        }
    }

    volatile bool internetAvailable = false; // boolean used elsewhere in code

    void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
    {
        if (e.Error == null)
        {
            internetAvailable = true;
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
            {
                // UI changes made here
            }));
        }
    }