apache HttpClient API 中的 setConnectionTimeout 、 setSoTimeout 和“http.connection-manager.timeout”有啥区别

Posted

技术标签:

【中文标题】apache HttpClient API 中的 setConnectionTimeout 、 setSoTimeout 和“http.connection-manager.timeout”有啥区别【英文标题】:What is the difference between the setConnectionTimeout , setSoTimeout and "http.connection-manager.timeout" in apache HttpClient APIapache HttpClient API 中的 setConnectionTimeout 、 setSoTimeout 和“http.connection-manager.timeout”有什么区别 【发布时间】:2013-08-13 15:23:13 【问题描述】:

这三者有什么区别(标记为cmets):

MultiThreadedHttpConnectionManager connManag =  new MultiThreadedHttpConnectionManager();
HttpConnectionManagerParams managParams = connManag.getParams();

managParams.setConnectionTimeout(connectiontimeout); // 1
managParams.setSoTimeout(sotimeout); //2

HttpMethodBase baseMethod = null;

try 
  HttpClient client = new HttpClient(connManag);
  client.getParams().setParameter("http.connection-manager.timeout", poolTimeout); //3

  baseMethod = new GetMethod(…);
  int statusCode = client.executeMethod(…);

  …

catch (ConnectTimeoutException cte )
  //Took too long to connect to remote host

catch (SocketTimeoutException ste)
  //Remote host didn’t respond in time

catch (Exception se)
  //Some other error occurred

finally 
  if (baseMethod != null)
    baseMethod.releaseConnection();

1. setConnectionTimeout - 如果它确定建立连接之前的超时时间。

2. setSoTimeout - 如果它确定两个连续数据包之间的不活动时间或时间差,

那么下面这个是做什么的:

3. "http.connection-manager.timeout"

【问题讨论】:

文档怎么说?他们沉默了吗? @Marko 无法理解这就是为什么在这里发布 您至少应该提及您已阅读它们,并指出困扰您的特定方面。这样一来,您的问题看起来就像您只是要求我们为您阅读文档。 【参考方案1】:

在最低级别的 HTTP 是 TCP 套接字。因此,当您请求 URL 并获得响应时,在较低级别会创建一个客户端 Socket,它与远程服务器 Socket 建立连接,发送一些数据并接收响应。

setConnectionTimeout :客户端尝试连接到服务器。这表示在建立连接或服务器响应连接请求之前经过的时间。

setSoTimeout:建立连接后,客户端socket发送请求后等待响应。这是从客户端在服务器响应之前向服务器发送请求以来经过的时间。请注意,这与服务器发送给客户端的HTTP Error 408 不同。换句话说,它在连接建立后两个连续数据包到达客户端之间的最大不活动时间

http.connection-manager.timeoutMultiThreadedHttpConnectionManager 使用 HTTP 连接池。它为每个主机设置了最大值和最小值。如果特定主机的所有连接都已达到最大值,则对同一主机的新连接请求将不得不等到现有连接中的任何一个空闲。此参数表示从发出连接请求到HttpConnectionManager 返回连接之前经过的时间。

【讨论】:

这意味着我们必须关闭套接字或连接 当你处理像HttpClient这样的API时,你不必直接处理套接字。即使在HttpClient 的情况下,也有一种方法(httpclient.getConnectionManager().shutdown();)可以关闭非常HttpClient,它可以完成关闭连接的工作。 但我不必关闭连接,因为我正在做连接池。我应该怎么做才能停止等待请求的响应。 ???但这就是你问的(_这意味着我们必须关闭套接字或连接_)。因为不等待回复,您已经在使用HttpConnectionManagerParams.setSoTimeout()【参考方案2】:

详细解释在 Apache HTTP 客户端站点的Connection management documentation 中提供。

CoreConnectionPNames.SO_TIMEOUT='http.socket.timeout': 以毫秒为单位定义套接字超时 (SO_TIMEOUT),即等待数据的超时时间,或者换句话说,最长不活动时间两个连续的数据包)。超时值为零被解释为无限超时。此参数需要 java.lang.Integer 类型的值。如果不设置该参数,读操作不会超时(无限超时)。

CoreConnectionPNames.CONNECTION_TIMEOUT='http.connection.timeout': 确定建立连接之前的超时时间(以毫秒为单位)。超时值为零被解释为无限超时。此参数需要 java.lang.Integer 类型的值。如果不设置此参数,连接操作不会超时(无限超时)。

连接管理器超时 (http.connection-manager.timeout) – 等待来自连接管理器/池的连接的时间

仅供参考

HttpParams httpParams = httpClient.getParams();
httpParams.setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, timeout * 1000);
httpParams.setParameter(CoreConnectionPNames.SO_TIMEOUT, timeout * 1000);

是另一种方法

HttpParams httpParams = httpClient.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, timeout * 1000);
HttpConnectionParams.setSoTimeout(httpParams, timeout * 1000);

【讨论】:

如何设置http.connection-manager.timeout,我找不到正确的方法。 回答我自己的评论,你应该这样做。 setConnectionRequestTimeout 是一个: RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(connectTimeout) .setConnectionRequestTimeout(connectionRequestTimeout) .setSocketTimeout(socketTimeout).build(); ...并将配置设置为HttpGet 或其他方法。 httpGet.setConfig(requestConfig);. 附注:在 4.5.7 中,根据 Javadoc,所有三个 args 都具有默认值 -1,这意味着“未定义(系统默认值)”。【参考方案3】:

简单来说:

连接超时:您的应用程序在尝试与服务器建立连接并且无法建立连接时等待的时间限制(地址错误,或服务器已关闭等...) 套接字超时:您的应用程序在连接到服务器后仍等待响应的时间限制(例如,延迟可能由服务器挂起引起) 连接管理器超时:当请求在队列中等待池中的一个请求被释放时,请求等待的时间限制。换句话说,在 HTTP 中,我们有一个最大大小的连接池。当应用程序有负载时,池可能已满,任何新请求都必须等待池中的另一个请求完成。

【讨论】:

值得补充的是,线程将wait INFINITELY 将连接释放回池。在可靠性和响应性很重要的应用程序中,这是一个非常糟糕的模式【参考方案4】:

这个序列图可能会有所帮助。

【讨论】:

优秀的图表 ;) @Maria 哪个序列图?在我的浏览器上看不到。有链接吗?

以上是关于apache HttpClient API 中的 setConnectionTimeout 、 setSoTimeout 和“http.connection-manager.timeout”有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

忽略 Apache HttpClient 4.3 中的 SSL 证书

Apache HttpClient之fluent API的使用

Apache HttpClient 读取响应乱码问题总结

Android API 23 - HttpClient 4.X 重新打包

Android 已弃用 apache 模块(HttpClient、HttpResponse 等)

android和httpClient