我可以在Android中为DefaultHttpClient设置getaddrinfo超时吗? [英] Can I set the getaddrinfo timeout in Android for DefaultHttpClient?

查看:152
本文介绍了我可以在Android中为DefaultHttpClient设置getaddrinfo超时吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个Android应用中,我正在尝试测试用户的互联网连接是否正常.如果您有兴趣,请问上一个问题在Android中检测有限的网络连接?

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 Detecting limited network connectivity in Android?

代码基本上是这样的:

try {
    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)
    {       
        return false;
    }
    return true;

} catch(Exception e) {
    return false;
}

我可以使用HttpConnectionParams控制Connection和Socket的超时.但是,如果我的设备已连接到Wifi,但wifi无法访问互联网,则我遇到的错误是:

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失败:EAI_NODATA(无地址 与主机名相关联)

libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address associated with hostname)

无法解析主机"www.example.com":没有与之关联的地址 主机名

Unable to resolve host "www.example.com": No address associated with hostname

哪个看起来像在DNS查找上超时.我可以控制DNS查找超时吗?除上述异常外,httpClient.execute大约需要45秒才能失败.我希望它早点放弃.

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.

推荐答案

我做了一些功课,看来您无法调整DNS查找超时.因此,我认为更好的方法是进行显式DNS查找,以便我可以控制它(并希望将结果缓存起来以加快下一次尝试的速度).因此,我想到了简单的方法:

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

,但这也有45秒的超时时间.其他人曾提到无法控制getByName()的超时时间 .最后,我偶然发现了一个简单的解决方案,只需在单独的线程中启动查找并管理自己的超时即可. 此博客文章很好地说明了这一点. /p>

but this also had a 45 second timeout. Others had mentioned that there was no control of the timeout for getByName(). Finally, I stumbled on a simple solution, just launch the lookup in a separate thread and manage your own timeout. This blog post shows this quite well.

private static boolean testDNS(String hostname) {
  try
  {
    DNSResolver dnsRes = new DNSResolver(hostname);
    Thread t = new Thread(dnsRes);
    t.start();
    t.join(1000);
    InetAddress inetAddr = dnsRes.get();            
    return inetAddr != null;
  }
  catch(Exception e)
  { 
    return false;
  }
}

private static class DNSResolver implements Runnable {
    private String domain;
    private InetAddress inetAddr;

    public DNSResolver(String domain) {
        this.domain = domain;
    }

    public void run() {
        try {
            InetAddress addr = InetAddress.getByName(domain);
            set(addr);
        } catch (UnknownHostException e) {                
        }
    }

    public synchronized void set(InetAddress inetAddr) {
        this.inetAddr = inetAddr;
    }
    public synchronized InetAddress get() {
        return inetAddr;
    }
}

使用此方法,我可以先测试设备是否可以解析主机名,然后再测试是否成功进行完整的连接测试.

Using this I can first test if the device can resolve the host name, then if it successful to the full connectivity test.

这篇关于我可以在Android中为DefaultHttpClient设置getaddrinfo超时吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆