android 2g移动网络 如何判断超时

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android 2g移动网络 如何判断超时相关的知识,希望对你有一定的参考价值。

HttpURLConnection conn = null;
try
URL url = new URL(urlstr);
conn = (HttpURLConnection)url.openConnection();
//连接超时时间
conn.setConnectTimeout(5*1000);
conn.setReadTimeout(5*1000);
conn.setRequestMethod("GET");
conn.connect();
if(conn.getResponseCode() != HttpURLConnection.HTTP_OK)
conn = null;

catch (Exception e)
e.printStackTrace();
conn = null;

return conn;


本人的代码如上,用http协议访问一个不存在的ip时,在wifi环境下没问题(getResponseCode()=-1),但当用2g移动网络时,getResponseCode()=200。 调试后发现在2g移动网络下访问一个不存在的ip时,会返回如下信息。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>730</title>
<meta http-equiv="Cache-Control" content="no-cache"/>
</head>
<body>
<p>
网关与远端服务器建立连接失败
</p>
</body>
</html>
怪不得getResponseCode()=200。
但问题就出来了,不知道怎样使得 在不同网络时,都能根据网络连接与否返回conn或null

参考技术A 太专业不是很懂啊

如何判断HttpClient何时超时?

据我所知,没有办法知道它特别是发生了超时。我不是在寻找合适的地方,还是我错过了更大的东西?

string baseAddress = "http://localhost:8080/";
var client = new HttpClient() 
{ 
    BaseAddress = new Uri(baseAddress), 
    Timeout = TimeSpan.FromMilliseconds(1) 
};
try
{
    var s = client.GetAsync("").Result;
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine(e.InnerException.Message);
}

返回:

发生了一个或多个错误。

任务被取消了。

答案

你需要等待GetAsync方法。如果它已超时,它将抛出一个TaskCanceledException。此外,GetStringAsyncGetStreamAsync内部处理超时,所以他们永远不会抛出。

string baseAddress = "http://localhost:8080/";
var client = new HttpClient() 
{ 
    BaseAddress = new Uri(baseAddress), 
    Timeout = TimeSpan.FromMilliseconds(1) 
};
try
{
    var s = await client.GetAsync();
}
catch(Exception e)
{
    Console.WriteLine(e.Message);
    Console.WriteLine(e.InnerException.Message);
}
另一答案

我正在复制同样的问题,这真的很烦人。我发现这些有用:

HttpClient - dealing with aggregate exceptions

Bug in HttpClient.GetAsync should throw WebException, not TaskCanceledException

一些代码以防链接无处可寻:

var c = new HttpClient();
c.Timeout = TimeSpan.FromMilliseconds(10);
var cts = new CancellationTokenSource();
try
{
    var x = await c.GetAsync("http://linqpad.net", cts.Token);  
}
catch(WebException ex)
{
    // handle web exception
}
catch(TaskCanceledException ex)
{
    if(ex.CancellationToken == cts.Token)
    {
        // a real cancellation, triggered by the caller
    }
    else
    {
        // a web request timeout (possibly other things!?)
    }
}
另一答案

我发现确定服务调用是否超时的最佳方法是使用取消令牌而不是HttpClient的超时属性:

var cts = new CancellationTokenSource();
cts.CancelAfter(timeout);

然后在服务调用期间处理CancellationException ...

catch(TaskCanceledException)
{
    if(!cts.Token.IsCancellationRequested)
    {
        // Timed Out
    }
    else
    {
        // Cancelled for some other reason
    }
}

当然,如果超时发生在服务端,那么应该能够通过WebException来处理。

另一答案

来自http://msdn.microsoft.com/en-us/library/system.net.http.httpclient.timeout.aspx

域名系统(DNS)查询最多可能需要15秒才能返回或超时。如果您的请求包含需要解析的主机名,并且您将Timeout设置为小于15秒的值,则可能需要15秒或更长时间才能引发WebException以指示请求超时。

然后,您可以访问Status属性,请参阅WebExceptionStatus

另一答案

基本上,您需要捕获OperationCanceledException并检查传递给SendAsync(或GetAsync,或您正在使用的任何HttpClient方法)的取消令牌的状态:

  • 如果它被取消(IsCancellationRequested为真),则表示该请求确实被取消了
  • 如果不是,则表示请求超时

当然,这不是很方便...如果超时,最好收到TimeoutException。我在这里提出了一个基于自定义HTTP消息处理程序的解决方案:Better timeout handling with HttpClient

另一答案
_httpClient = new HttpClient(handler) {Timeout = TimeSpan.FromSeconds(5)};

是我通常做的,似乎对我来说非常好,在使用代理时特别好。

以上是关于android 2g移动网络 如何判断超时的主要内容,如果未能解决你的问题,请参考以下文章

Android - 获取支持的移动网络类型列表

利用CoreTelephony获取用户当前网络状态(判断2G,3G,4G)

js-获取用户移动端网络类型:wifi4g3g2g...

Android开发之网络

如何让安卓手机强制4G网络模式

android判断移动网络是不是打开