【问题标题】:Android HttpURLConnection Connectivity TimeoutAndroid HttpURLConnection 连接超时
【发布时间】:2014-10-03 09:13:16
【问题描述】:

我在使用 Android 4.1.2 和 4.2.2 时遇到间歇性连接问题,因此 HTTP 堆栈似乎完全超时(DNS 查找和 TCP/IP 仍然有效,我可以使用 ADB SHELL 进行检查)。

这些连接是通过 GPRS 而不是通过 WiFi 失败的。

当使用 SHELL 检查 netstat 时,我可以看到连接在等待 SYN_SENT,当检查服务器上的防火墙时,我们可以看到它已经响应了 SYN 请求,但没有收到来自设备的任何回复.在此中断期间,设备上的所有 HTTP 流量似乎都失败了。 Exchange 不再有效,您无法使用任何常用浏览器(Firefox、Chrome)请求任何页面,即使设备报告网络并且您可以拨打/接听电话。

我的应用程序通过 HTTP 和 HTTPS 进行通信,并且在此中断期间都失败了。 POST 和 GET 到我的 JSON Web 服务,请求挂起并抛出:

java.net.SocketTimeoutException: failed to connect to mywebaddress.com/1.1.1.1 (port 443) after 10000ms

如果它在连接时遇到问题,这是正常的,因为它尊重我在下面使用 HttpURLConnection 设置的超时。

我使用的代码如下,位于 Async 类中。这通常包含在连接循环中,具体取决于消息的重要性。最多可以调用 3 次,每次调用之间有 15 秒的间隔。

HttpURLConnection conn = null;
BufferedReader reader = null;

try
{           
    // Uses ConnectivityManager.getActiveNetworkInfo()
    // Returns true, the Android OS reports a connection
    if(myApp.hasNetworkConnection)
    {
        conn = (HttpURLConnection)endpoint.openConnection();
        conn.setConnectTimeout(10000);
        conn.setReadTimeout(20000);

        reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));

        StringBuffer strResults = new StringBuffer();
        String strLine = "";

        while ((strLine = reader.readLine()) != null) 
        {
            strResults.append(strLine);
        }

        log(strResults.toString());
    }

}
catch(Exception ex)
{
    log(ex.getMessage());
}
finally
{
    if(reader != null)
        try
        {
            reader.Close();
            reader = null;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }

    if(connection != null)
    {
        connection.disconnect();
        connection = null;
    }
}

我想知道过去是否有人遇到过这种情况,定期尝试连接的方法是错误的方法并耗尽连接池吗?

创建的连接会定期触发,并且它不会(当前)将连接批处理在一起。

只是为了分享更多信息,这是我们遇到中断时 netstat 在设备(ADB Shell)上显示的内容。两个“ESTABLISHED”连接是 TCP 连接而不是 HTTP 请求。手机有信号,数据符号显示连接。

【问题讨论】:

    标签: android networking httpurlconnection


    【解决方案1】:
    try this
    
      try {
       HttpURLConnection.setFollowRedirects(false);
       HttpURLConnection con = (HttpURLConnection) new URL(url).openConnection();
       con.setRequestMethod("HEAD");
    
       con.setConnectTimeout(5000); //set timeout to 5 seconds
    
       return (con.getResponseCode() == HttpURLConnection.HTTP_OK);
    } catch (java.net.SocketTimeoutException e) {
       return false;
    } catch (java.io.IOException e) {
       return false;
    }
    

    【讨论】:

    • 如果你不介意,添加setFollowRedirects的目的是什么?从当前的响应来看,服务器似乎没有重定向到任何地方。此外,setRequestMethod 只会返回状态码。效率更高,但还有其他原因吗?
    【解决方案2】:

    只是想我会更新,以防其他人遇到此问题。

    这里的问题不在于 Android,而在于应用程序正在调用的 Web 服务。查看它,当它调用 JSON Web 服务时,返回响应(如果有的话)的时间比预期的要长得多(长达一分钟以上),并且该响应始终为 200/OK。

    由于我们的请求使 Android HTTP 堆栈饱和,最终它们没有在足够好的时间内清除并且会冻结设备。

    我通过将连接和读取超时设置为更合适的值而不是“0”(无限)为我的代码添加了更好的容错性,我们已经研究过修改 Web 服务,以便长时间运行的进程返回 201/已接受状态以便设备可以继续做它自己的工作。一旦服务器处理完成,我们会通过其他方式(Google Cloud Message)回调设备。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-01
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      • 2014-01-06
      • 2017-09-05
      • 2013-12-01
      • 2018-10-27
      相关资源
      最近更新 更多