可以设置python getaddrinfoo 超时在 Android 中的 DefaultHttpClient 吗

2892人阅读
android(159)
昨天看了一篇HttpClient的设置超时时间,本来以为今天到公司就能把问题给解决了。结果发现DefaultHttpClient没有设置超时时间。然后继续寻找,终于发现了DefaultHttpClient怎么设置超时的了。
其实是在HttpConnectionParams里设置的。我自己写了一个继承DefaultHttpClient的类,以后使用用这个就行了:
* 封装超时的HTTPclient
* @author wangfeng
* @date date
public class MyHttpClient extends DefaultHttpClient{
* 获取 HttpClient,主要是封装了超时设置
* @param rTimeOut 请求超时
* @param sTimeOut 等待数据超时
public DefaultHttpClient getHttpClient(int rTimeOut,int sTimeOut){
BasicHttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, rTimeOut);
HttpConnectionParams.setSoTimeout(httpParams, sTimeOut);
DefaultHttpClient client = new DefaultHttpClient(httpParams);
如何使用:
HttpPost httpRequest =new HttpPost(validateUrl);
//Post运作传送变数必须用NameValuePair[]阵列储存
//传参数 服务端获取的方法为request.getParameter(&name&)
List params=new ArrayList();
params.add(new BasicNameValuePair(&username&,userName));
params.add(new BasicNameValuePair(&password&,password));
//发出HTTP request
httpRequest.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8));
//取得HTTP response
HttpResponse httpResponse =
httpResponse=new MyHttpClient().getHttpClient().execute(httpRequest);
}catch(Exception e){
isNetError =
System.out.println(&netError&);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:589901次
积分:10725
积分:10725
排名:第1020名
原创:482篇
转载:46篇
评论:108条
(7)(3)(1)(1)(1)(2)(6)(2)(6)(5)(8)(7)(17)(2)(17)(10)(16)(12)(14)(13)(9)(15)(15)(15)(23)(25)(30)(6)(1)(24)(50)(33)(22)(30)(22)(10)(9)(12)(13)(2)(1)(2)(1)(3)(1)(3)(4)java - Can I set the getaddrinfo timeout in Android for DefaultHttpClient? - Stack Overflow
to customize your list.
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
J it only takes a minute:
Join the Stack Overflow community to:
Ask programming questions
Answer and help your peers
Get recognized for your expertise
In an Android app, I'm trying to test that the user has a working Internet connection. If you are interested, there is some background in a previous question
The code is basically like:
HttpParams myParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(myParams, 10000);
HttpConnectionParams.setSoTimeout(myParams, 10000);
httpClient = new DefaultHttpClient(myParams);
request = new HttpHead(url);
response = httpClient.execute(request);
statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200)
} catch(Exception e) {
I can control the timeouts for Connection and Socket using HttpConnectionParams. But, if my device is connected to Wifi, but the wifi has no Internet access, the error I'm getting in the exception is:
libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address
associated with hostname)
Unable to resolve host "": No address associated with
Which looks like it timed out on a DNS lookup. Can I control the timeout of the DNS Lookup? httpClient.execute is taking about 45 seconds to fail with the exception noted above. I'd like it to give up sooner.
8,910103668
I did a little homework and it seems that you cannot adjust the DNS lookup timeout. So, I figured a better approach would be to an explicit DNS lookup so I could control it (and hopefully have the result cached to speed the next attempt). So that led me to the simple:
InetAddress addr = InetAddress.getByName(hostname);
but this also had a 45 second timeout. Others had mentioned that there was . Finally, I stumbled on a simple solution, just launch the lookup in a separate thread and manage your own timeout.
shows this quite well.
private static boolean testDNS(String hostname) {
DNSResolver dnsRes = new DNSResolver(hostname);
Thread t = new Thread(dnsRes);
t.start();
t.join(1000);
InetAddress inetAddr = dnsRes.get();
return inetAddr !=
catch(Exception e)
private static class DNSResolver implements Runnable {
private InetAddress inetA
public DNSResolver(String domain) {
this.domain =
public void run() {
InetAddress addr = InetAddress.getByName(domain);
set(addr);
} catch (UnknownHostException e) {
public synchronized void set(InetAddress inetAddr) {
this.inetAddr = inetA
public synchronized InetAddress get() {
return inetA
Using this I can first test if the device can resolve the host name, then if it successful to the full connectivity test.
8,910103668
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabled2468人阅读
上一篇文章介绍了使用HttpURLConnection来完成对于HTTP协议的支持。现在介绍一个新的方式来访问Web站点,那就是HttpClient。
HttpClient是Apache开源组织提供的一个开源的项目,从名字上就可以看出,它是一个简单的HTTP客户端(并不是浏览器),可以发送HTTP请求,接受HTTP响应。但是不会缓存服务器的响应,不能执行HTTP页面中签入嵌入的JS代码,自然也不会对页面内容进行任何解析、处理,这些都是需要开发人员来完成的。
现在Android已经成功集成了HttpClient,所以开发人员在Android项目中可以直接使用HttpClient来想Web站点提交请求以及接受响应,如果使用其他的Java项目,需要引入进相应的Jar包。HttpClient可以在官网上下载:
HttpClient
HttpClient其实是一个interface类型,HttpClient封装了对象需要执行的Http请求、身份验证、连接管理和其它特性。从文档上看,HttpClient有三个已知的实现类分别是:AbstractHttpClient,&AndroidHttpClient,&DefaultHttpClient,会发现有一个专门为Android应用准备的实现类AndroidHttpClient,当然使用常规的DefaultHttpClient也可以实现功能,但是既然开发的是Android应用程序,还是使用Android专有的实现类,一定有其优势。
从两个类包所有在位置就可以看出区别,AndroidHttpClient定义在android.net.http.AndroidHttpClient包下,属于Android原生的http访问,而DefaultHttpClient定义在org.apache.http.impl.client.DefaultHttpClient包下,属于对apche项目的支持。而AndroidHttpClient没有公开的构造函数,只能通过静态方法newInstance()方法来获得AndroidHttpClient对象。
AndroidHttpClient对于DefaultHttpClient做了一些改进,使其更使用用于Android项目:
关掉过期检查,自连接可以打破所有的时间限制。
可以设置ConnectionTimeOut(连接超时)和SoTimeout(读取数据超时)。
关掉重定向。
使用一个Session缓冲用于SSL Sockets。
如果服务器支持,使用gzip压缩方式用于在服务端和客户端传递的数据。
默认情况下不保留Cookie。
简单来说,送HttpClient发送请求、接收响应都很简单,只需要几个步骤即可:
创建HttpClient对象。
创建对应的发送请求的对象,如果需要发送GET请求,则创建HttpGet对象,如果需要发送POST请求,则创建HttpPost对象。
对于发送请求的参数,GET和POST使用的方式不同,GET方式可以使用拼接字符串的方式,把参数拼接在URL结尾;POST方式需要使用setEntity(HttpEntity entity)方法来设置请求参数。
调用HttpClient对象的execute(HttpUriRequest request)发送请求,执行该方法返回一个HttpResponse对象。
调用HttpResponse的对应方法获取服务器的响应头、响应内容等。
DefaultHttpClient
先看看使用DefaultHttpClient方式发送Web站点请求,上面已经简要说明了步骤,在这里简要说明一个参数的传递问题,对于GET方式,只需要拼接字符串就在URL结尾即可,但是对于POST方式,需要传递HttpEntity对象,HttpEntity为一个接口,有多个实现类,可以使用其间接子继承,UrlEncodedFormEntity类来保存请求参数,并传递给HttpPost。
此例子简单实现了在Android客户端使用DefaultHttpClient实现一个Http站点登陆的实现,使用的是POST传递,其传递值只需要传递username+password即可,当传递的数据为admin+123则认为登陆成功。Web站点使用.net的架构,一个一般处理程序,简单的比对账户密码,这里就不在此讲解。
因为Android4.0之后对使用网络有特殊要求,已经无法再在主线程中访问网络了,必须使用多线程访问的模式,其他的一些信息在代码注释中已经说明。
&DefaultHttpClient-Code
1 package com.bgxt.httpU
3 import java.io.ByteArrayOutputS
4 import java.io.IOE
5 import java.io.InputS
6 import java.io.UnsupportedEncodingE
7 import java.util.ArrayL
8 import java.util.HashM
9 import java.util.L
10 import java.util.M
12 import org.apache.http.HttpR
13 import org.apache.http.NameValueP
14 import org.apache.http.client.ClientProtocolE
15 import org.apache.http.client.entity.UrlEncodedFormE
16 import org.apache.http.client.methods.HttpP
17 import org.apache.http.impl.client.DefaultHttpC
18 import org.apache.http.message.BasicNameValueP
20 public class httpClientUtils implements Runnable {
* 对于Android4.0之上的环境下,不能在主线程中访问网络 所以这里另新建了一个实现了Runnable接口的Http访问类
public httpClientUtils(String username, String password) {
// 初始化用户名和密码
this.username =
this.password =
public void run() {
// 设置访问的Web站点
String path = &http://192.168.1.103:1231/loginas.ashx&;
// 设置Http请求参数
Map&String, String& params = new HashMap&String, String&();
params.put(&username&, username);
params.put(&password&, password);
String result = sendHttpClientPost(path, params, &utf-8&);
// 把返回的接口输出
System.out.println(result);
* 发送Http请求到Web站点
* @param path
Web站点请求地址
* @param map
Http请求参数
* @param encode
* @return Web站点响应的字符串
private String sendHttpClientPost(String path, Map&String, String& map,
String encode) {
List&NameValuePair& list = new ArrayList&NameValuePair&();
if (map != null && !map.isEmpty()) {
for (Map.Entry&String, String& entry : map.entrySet()) {
// 解析Map传递的参数,使用一个键值对对象BasicNameValuePair保存。
list.add(new BasicNameValuePair(entry.getKey(), entry
.getValue()));
// 实现将请求 的参数封装封装到HttpEntity中。
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, encode);
// 使用HttpPost请求方式
HttpPost httpPost = new HttpPost(path);
// 设置请求参数到Form中。
httpPost.setEntity(entity);
// 实例化一个默认的Http客户端
DefaultHttpClient client = new DefaultHttpClient();
// 执行请求,并获得响应数据
HttpResponse httpResponse = client.execute(httpPost);
// 判断是否请求成功,为200时表示成功,其他均问有问题。
if (httpResponse.getStatusLine().getStatusCode() == 200) {
// 通过HttpEntity获得响应流
InputStream inputStream = httpResponse.getEntity().getContent();
return changeInputStream(inputStream, encode);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
return &&;
* 把Web站点返回的响应流转换为字符串格式
* @param inputStream
* @param encode
* @return 转换后的字符串
private String changeInputStream(InputStream inputStream, String encode) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int len = 0;
String result = &&;
if (inputStream != null) {
while ((len = inputStream.read(data)) != -1) {
outputStream.write(data, 0, len);
result = new String(outputStream.toByteArray(), encode);
} catch (IOException e) {
e.printStackTrace();
AndroidHttpClient
使用AndroidHttpClient的方式和DefaultHttpClient差不多,不多的几点区别上面已经说明,但是在此例子中没有体现。有一点需要注意的是,AndroidHttpClient是一个final类,也没有公开的构造函数,所以无法使用new的形式对其进行实例化,必须使用AndroidHttpClient.newInstance()方法获得AndroidHttpClient对象。
示例中依然是使用POST请求,实现的功能和DefaultHttpClient示例一样。细节部分已经在注释中体现,直接看代码即可。
1 package com.bgxt.httpU
3 import java.io.ByteArrayOutputS
4 import java.io.IOE
5 import java.io.InputS
6 import java.io.UnsupportedEncodingE
7 import java.util.ArrayL
8 import java.util.HashM
9 import java.util.L
10 import java.util.M
12 import org.apache.http.HttpR
13 import org.apache.http.NameValueP
14 import org.apache.http.client.ClientProtocolE
15 import org.apache.http.client.HttpC
16 import org.apache.http.client.entity.UrlEncodedFormE
17 import org.apache.http.client.methods.HttpP
18 import org.apache.http.impl.client.DefaultHttpC
19 import org.apache.http.message.BasicNameValueP
21 import android.net.http.AndroidHttpC
23 public class AndroidHttpClientUtils implements Runnable {
public AndroidHttpClientUtils(String username, String password) {
// 初始化用户名和密码
this.username =
this.password =
public void run() {
// 设置访问的Web站点
String path = &http://192.168.1.103:1231/loginas.ashx&;
//设置Http请求参数
Map&String, String& params = new HashMap&String, String&();
params.put(&username&, username);
params.put(&password&, password);
String result = sendHttpClientPost(path, params, &utf-8&);
//把返回的接口输出
System.out.println(result);
* 发送Http请求到Web站点
* @param path Web站点请求地址
* @param map Http请求参数
* @param encode 编码格式
* @return Web站点响应的字符串
private String sendHttpClientPost(String path,Map&String, String& map,String encode)
List&NameValuePair& list=new ArrayList&NameValuePair&();
if(map!=null&&!map.isEmpty())
for(Map.Entry&String, String& entry:map.entrySet())
//解析Map传递的参数,使用一个键值对对象BasicNameValuePair保存。
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
//实现将请求 的参数封装封装到HttpEntity中。
UrlEncodedFormEntity entity=new UrlEncodedFormEntity(list, encode);
//使用HttpPost请求方式
HttpPost httpPost=new HttpPost(path);
//设置请求参数到Form中。
httpPost.setEntity(entity);
//实例化一个默认的Http客户端,使用的是AndroidHttpClient
HttpClient client=AndroidHttpClient.newInstance(&&);
//执行请求,并获得响应数据
HttpResponse httpResponse= client.execute(httpPost);
//判断是否请求成功,为200时表示成功,其他均问有问题。
if(httpResponse.getStatusLine().getStatusCode()==200)
//通过HttpEntity获得响应流
InputStream inputStream=httpResponse.getEntity().getContent();
return changeInputStream(inputStream,encode);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return &&;
* 把Web站点返回的响应流转换为字符串格式
* @param inputStream 响应流
* @param encode 编码格式
* @return 转换后的字符串
String changeInputStream(InputStream inputStream,
String encode) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int len = 0;
String result=&&;
if (inputStream != null) {
while ((len = inputStream.read(data)) != -1) {
outputStream.write(data,0,len);
result=new String(outputStream.toByteArray(),encode);
} catch (IOException e) {
e.printStackTrace();
在本文的示例中,环境是使用的Android项目,可以对其进行简单的界面布局,如图:
如果输入用户和密码为:admin+123,则可以再LogCat中查看到登录成功。
示例代码下载地址:
最近的两次博客中,已经分别介绍了HttpUrlConnection和HttpClient两种方式,通过Http协议对Web站点的访问。如果还不了解HttpURLConnection的读者,可以看看“”。
根据官方文档上说的显示,Android包括两个Http客户端:HttpURLConnection和Apache HttpClient。并且都支持HTTPS,流媒体上传下载,并且可配置超时以及支持IPv6和连接池技术。但是因为移动设备的局限性,HttpURLConnection会是比Apache Http更好的选择,因为其API简单,运行消耗内存小,并且具有公开化的压缩算法,以及响应缓存,能更好的减少网络使用,提供运行速度和节省电池。
但是也不能否认Apache HttpClient,它有大量的灵活的API,实现比较稳定,少有Bug,可造成的问题就是很难在不影响其兼容性的情况下对其进行改进了。现在Android开发者已经慢慢放弃Apache HttpClient的使用,转而使用HttpURLConnection。但是对于Android2.2之前的版本,HttpURLConnection具有一个致命的BUG,在响应输入流InputStream中调用.Close()方法将会阻碍连接池,因为这个BUG,只能放弃连接池的使用,但是Apache HttpClient不存在这个问题,当然Android2.3之后的版本中,HttpURLConnection已经解决了这个BUG,可以放心使用。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:6145132次
积分:70424
积分:70424
排名:第14名
原创:435篇
转载:4678篇
译文:22篇
评论:1557条
文章:21篇
阅读:40046
文章:15篇
阅读:30317
文章:22篇
阅读:190497
(4)(8)(28)(21)(47)(1)(1)(8)(170)(814)(1012)(1351)(969)(262)(207)(2)(3)(2)(61)(19)(2)(28)(22)(37)(1)(3)(4)(6)(9)(10)(26)}

我要回帖

更多关于 getaddrinfo failed 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信