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
如何判断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
。此外,GetStringAsync
和GetStreamAsync
内部处理超时,所以他们永远不会抛出。
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移动网络 如何判断超时的主要内容,如果未能解决你的问题,请参考以下文章