http连接超时问题

时间:2011-01-02 09:13:48

标签: java android timeout apache-httpclient-4.x

当我尝试使用HttpClient连接时,我遇到了一个问题 到网址。即使在我设置之后,http连接也需要更长的时间才能超时 连接timeoout。

int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);

int timeoutSocket = 5000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

大部分时间都很完美。然而,每隔一段时间,http连接就会永远运行而忽略setconnectiontimeout,特别是当手机连接到wifi时,手机就是空转。

所以在手机闲置后,我第一次尝试连接时,http连接会忽略setconnectiontimeout并永远运行,在我取消它并再试一次后,它每次都像魅力一样。但是有一次它不起作用会产生threadtimeout错误,我尝试使用不同的线程,它可以工作,但我知道该线程已经运行了很长时间。

我明白wifi会在闲置时进入睡眠状态,但我不明白为什么忽略了setconnectiontimeout

任何人都可以提供帮助,我非常感激。

10 个答案:

答案 0 :(得分:10)

不确定这是否对您有所帮助,但我认为值得在此分享。在玩超时的东西时,我发现你可以指定第三种超时类型:

// the timeout until a connection is established
private static final int CONNECTION_TIMEOUT = 5000; /* 5 seconds */

// the timeout for waiting for data
private static final int SOCKET_TIMEOUT = 5000; /* 5 seconds */

// ----------- this is the one I am talking about:
// the timeout until a ManagedClientConnection is got 
// from ClientConnectionRequest
private static final long MCC_TIMEOUT = 5000; /* 5 seconds */

...

HttpGet httpGet = new HttpGet(url);
setTimeouts(httpGet.getParams());

...

private static void setTimeouts(HttpParams params) {
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 
        CONNECTION_TIMEOUT);
    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, SOCKET_TIMEOUT);
    params.setLongParameter(ConnManagerPNames.TIMEOUT, MCC_TIMEOUT);
}

答案 1 :(得分:1)

Thread t=new Thread()
{
  public void run()
  {
    try 
    {
      Thread.sleep(absolutetimeout);
      httpclient.getConnectionManager().closeExpiredConnections();
      httpclient.getConnectionManager().closeIdleConnections(absolutetimeout,TimeUnit.MILLISECONDS);
      httpclient.getConnectionManager().shutdown();
      log.debug("We shutdown the connection manager!");
    }
    catch(InterruptedException e)
    {}
  }
};

t.start();
HttpResponse res= httpclient.execute(httpget);
t.interrupt();

这是否符合你们所有人的建议?

我不确定如何在启动后取消执行,但这似乎对我有用。我不确定线程​​中的三行中的哪一行是神奇的,或者它是否都是它们的组合。

答案 2 :(得分:1)

我遇到了同样的问题,我想也许Android不支持这个参数。 在我的情况下,我测试了ThreadSafeClientConnManager的所有三个参数

params.setParameter( ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(20) );
params.setIntParameter( ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 200 );
params.setLongParameter( ConnManagerPNames.TIMEOUT, 10 );
ThreadSafeClientConnManager connmgr = new ThreadSafeClientConnManager( params );

第一个和第二个工作正常,但第三个没有记录的工作。当DefaultHttpClient#execute()执行时,没有抛出异常并且执行线程被无限期地阻塞。

http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e650
“...通过将'http.conn-manager.timeout'设置为正值,可以确保连接管理器不会无限期地阻塞连接请求操作。如果连接请求无法在给定时间段内得到服务,ConnectionPoolTimeoutException将是抛出“。

答案 3 :(得分:0)

您可以自己管理超时,这样您就可以确信无论连接处于什么状态,除非您收到可接受的响应,否则您的超时将会触发,http请求将被中止。

答案 4 :(得分:0)

我在android上遇到类似的超时问题。为了解决这个问题,我所做的就是在我尝试建立连接时以及在连接的任何读取或写入期间使用命令不让电话空闲。在这种情况下,它可能值得一试。

答案 5 :(得分:0)

虽然我没有在Android平台上看过这个,但我在其他平台上看到过类似的东西,这些情况下的解决方案是自己管理超时。在提出请求时,启动另一个线程(超时线程)。超时线程倒计时所需的时间。如果在收到任何数据之前超时到期,则超时线程将取消原始请求,并重试新请求。更难编码,但至少你知道它会起作用。

答案 6 :(得分:0)

从你的片段开始,如果你在调用HttpClient.executeMethod(..)之前设置超时,那么最终不清楚。所以这是我的猜测。

答案 7 :(得分:0)

好吧,如果您将空闲/多任务转移到另一个应用程序,那么正在运行的线程可能会被停止并销毁。也许您应该将连接代码放在服务中?:

http://developer.android.com/reference/android/os/AsyncTask.html http://developer.android.com/reference/android/app/IntentService.html

答案 8 :(得分:0)

您是如何进行HTTP连接的?这看起来像一个线程问题。如果您使用后台线程,则线程可能会随着注册的任何超时一起被终止。它下次运行的事实告诉我你的代码将工作,如果你在Android组件中进行调用并自己管理WAKE_LOCK。无论如何,请发布有关呼叫机制的更多信息?

答案 9 :(得分:0)

问题可能出在Apache HTTP Client中。见HTTPCLIENT-1098。 已在4.1.2中修复。

超时异常会尝试将DNS反转为IP,以便进行日志记录。这需要额外的时间,直到实际触发异常。