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


当前回答

对于我的应用程序,我们也通过下载小文件进行测试。

string remoteUri = "https://www.microsoft.com/favicon.ico"

WebClient myWebClient = new WebClient();

try
{
    byte[] myDataBuffer = myWebClient.DownloadData (remoteUri);
    if(myDataBuffer.length > 0) // Or add more validate. eg. checksum
    {
        return true;
    }
}
catch
{
    return false;
}

也。有些ISP可能使用中间服务器缓存文件。添加未使用的随机参数。https://www.microsoft.com/favicon.ico?req=random_number 可以防止缓存。

其他回答

接受的答案很快就成功了,但当没有连接时,失败的速度非常慢。所以我想建立一个健壮的连接检查,它会更快地失败。

据说不是所有环境都支持ping,所以我从接受的答案开始,并从这里添加了一个带有自定义超时的WebClient。你可以选择任何超时,但3秒对我来说是通过wifi连接的。我尝试添加一个快速迭代(1秒),如果第一个迭代失败,则添加一个缓慢迭代(3秒)。但是这没有意义,因为这两个迭代总是失败(当没有连接时)或总是成功(当连接时)。

我正在连接AWS,因为我想在连接测试通过时上传一个文件。

public static class AwsHelpers
{
    public static bool GetCanConnectToAws()
    {
        try
        {
            using (var client = new WebClientWithShortTimeout())
            using (client.OpenRead("https://aws.amazon.com"))
                return true;
        }
        catch
        {
            return false;
        }
    }
}

public class WebClientWithShortTimeout: WebClient
{
    protected override WebRequest GetWebRequest(Uri uri)
    {
        var webRequest = base.GetWebRequest(uri);
        webRequest.Timeout = 5000;
        return webRequest;
    }
}

通过ping谷歌测试网络连接:

new Ping().Send("www.google.com.mx").Status == IPStatus.Success

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

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

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

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

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

我已经看到了上面列出的所有选项,唯一可行的选项来检查互联网是否可用是“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的情况下,没有办法知道互联网连接是否可用。

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