关于java:http连接超时问题

http connection timeout issues

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

1
2
3
4
5
int timeoutConnection = 5000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);

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

大多数情况下,它都能完美运行。但是,每隔一段时间,http连接将永远运行一次,并且会忽略setconnectiontimeout,尤其是当电话连接到wifi且电话处于空闲状态时。

因此,在电话空闲之后,我第一次尝试连接时,http连接会忽略setconnectiontimeout并永远运行,在我取消并重试后,每次连接都像魅力一样。但是那个不起作用的时间会创建一个threadtimeout错误,我尝试使用其他线程,它可以工作,但是我知道该线程运行了很长时间。

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

任何人都可以提供帮助,非常感谢您。


不确定这是否对您有帮助,但是我认为值得在这里分享。我发现在使用超时内容时,您可以分配第三种超时类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 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);
}


我遇到了同样的问题,我想也许Android不支持该参数。
就我而言,我测试了ThreadSafeClientConnManager

的所有三个参数

1
2
3
4
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将被设置为抛出。"


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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();

是不是按照大家的建议?

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


问题可能出在Apache HTTP客户端中。参见HTTPCLIENT-1098。
在4.1.2。

中已修复

出于日志记录目的,超时异常尝试将DNS反向IP。在实际触发异常之前,这需要花费额外的时间。


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


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

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


从您的摘录中,最终还不清楚在调用HttpClient.executeMethod(..)之前是否设置了超时。这就是我的猜测。


尽管我没有在Android平台上看到此消息,但在其他平台上也看到了类似的事情,在这些情况下,解决方案是自己管理超时。发出请求时,启动另一个线程(超时线程)。超时线程倒计时所需的时间。如果超时在您收到任何数据之前到期,则超时线程会取消原始请求,然后重试一个新请求。很难编写代码,但至少您知道它会起作用。


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


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