java-commons-HttpClient超时设置setConnectionT…
2018-06-18 03:50:01来源:未知 阅读 ()
http是基于TCP/IP进行通信的,tcp通过3次握手建立连接,并最终以4次挥手终止通信。
知乎上对三次握手和四次挥手有如下解释:
作者:知乎用户
链接:https://www.zhihu.com/question/67772889/answer/256760079
来源:知乎
http是应用层协议,主要依赖于运输层TCP协议(HTTP协议没有规定具体使用哪个运输层协议)。
tcp连接建立和断开方式涉及到客户端和服务器端的端口,缓存等资源的分配与释放问题。建立连接时,主动连接方(客户端)向服务器请求建立连接(SYN),服务器端收到后会给客户端响应(ack),表示它这边准备好连接了,但是他要确保客户端收到了它的响应,于是需要第三个数据包 客户端向服务器端确认(ack),这样相互确认之后服务器端就可以给这条连接分配必要的端口、缓存等资源。 假设只有两次数据包交换就分配资源,若服务器端响应客户端连接请求的包丢失了,客户端会认为服务器未响应,放弃本次连接请求,而服务器端之前分配的资源就会被闲置浪费。 更多次的报文交换是可以的,但是完全没有必要。 三次交换是建立连接所需最少的数量。
断开连接时, 任务先完成的一方(这里假设是客户端)会向另一方(即服务端)发送断开请求(FIN),表示自己这一方传输任务已经完成,服务器端收到后会响应。 但是这里 服务器端传送给客户端的数据可能还没有完,他需要维持当前连接来完成剩余的传输任务,即客户端还不能释放当前连接所需的资源。当服务端数据传输任务完成后,他会向客户端发送断开请求(FIN),客户端响应。 这样双方相互确认数据传输完成,可以断开连接,分别释放当前连接占用的系统资源,而不是提前释放导致传输的数据丢失。
httpConnection有两个重要的属性:http.connection.timeout和http.socket.timeout。connection timeout是建立连接的超时时间,socket timeout表示的是等待服务端响应数据的超时时间。
commons-httpclient 3.1里HttpConnectionParams.java里有如下2个方法:
/** * Sets the timeout until a connection is etablished. A value of zero * means the timeout is not used. The default value is zero. * * @param timeout Timeout in milliseconds. */ public void setConnectionTimeout(int timeout) { setIntParameter(CONNECTION_TIMEOUT, timeout); } /** * Sets the default socket timeout (<tt>SO_TIMEOUT</tt>) in milliseconds which is the * timeout for waiting for data. A timeout value of zero is interpreted as an infinite * timeout. This value is used when no socket timeout is set in the * {@link HttpMethodParams HTTP method parameters}. * * @param timeout Timeout in milliseconds */ public void setSoTimeout(int timeout) { setIntParameter(SO_TIMEOUT, timeout); }
如下示例代码,可以模拟ConnectTimeoutException和SocketTimeoutException
import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpException; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; import java.io.IOException; public class HttpclientTimeoutTest { public static void main(String[] args) { HttpClient client = new HttpClient(); HttpMethod method = new GetMethod("https://linkedin.com/company/stack-overflow"); client.getHttpConnectionManager().getParams() .setConnectionTimeout(10); client.getHttpConnectionManager().getParams().setSoTimeout(1000); System.out.println("begin.."); long start = System.currentTimeMillis(); try { int statusCode = client.executeMethod(method); System.out.println(statusCode); byte[] responseBody = null; responseBody = method.getResponseBody(); String result = new String(responseBody); System.out.println(result); } catch (HttpException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { System.out.println("end..Duration MS:" + (System.currentTimeMillis() - start)); } } }
这里,将建立连接的超时时间设置为小到10ms。即可复现出来ConnectTimeoutException。
begin.. org.apache.commons.httpclient.ConnectTimeoutException: The host did not accept the connection within timeout of 10 ms at org.apache.commons.httpclient.protocol.ReflectionSocketFactory.createSocket(ReflectionSocketFactory.java:155) at org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory.createSocket(SSLProtocolSocketFactory.java:130) at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) at com.emax.paycenter.HttpclientTimeoutTest.main(HttpclientTimeoutTest.java:24) Caused by: java.net.SocketTimeoutException: connect timed out at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method) at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:85) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182) at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:579) at sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:618) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.apache.commons.httpclient.protocol.ReflectionSocketFactory.createSocket(ReflectionSocketFactory.java:140) ... 7 more end..Duration MS: 1064
将读取数据的响应超时时间设置为小到10ms,即可复现出来SocketTimeoutException。
begin.. java.net.SocketTimeoutException: Read timed out at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:152) at java.net.SocketInputStream.read(SocketInputStream.java:122) at sun.security.ssl.InputRecord.readFully(InputRecord.java:442) at sun.security.ssl.InputRecord.read(InputRecord.java:480) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312) at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702) at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) at org.apache.commons.httpclient.HttpConnection.flushRequestOutputStream(HttpConnection.java:828) at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2116) at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096) at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398) at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397) at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323) at com.emax.paycenter.HttpclientTimeoutTest.main(HttpclientTimeoutTest.java:25) end..Duration MS: 1516
具体应用中,需要以实际需要来做超时设置。
references:
-
java-commons-HttpClient超时设置setConnectionTimeout和setSoTimeout
- 使用httpclient必须知道的参数设置及代码写法、存在的风险
文中分析了httpclient3.*的一些漏洞。推荐使用httpclient4.2.3。1. 将connection请求头设置为close,则会关闭连接socket。(如果是keep-alive ,不会关闭)2、在使用httpclient3.1时(4.2.3没问题);尽量不要调用 byte[] getResponseBody() :因为如果Content-Length没设置或者传输的数据大于1M,会有大量冗余日志。
-
HTTPS 工作原理和 TCP 握手机制
分析了TCP为什么需要3次握手,和为什么需要4次挥手
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- IDEA 设置热部署 Devtools 2020-06-10
- java环境教程:Tomcat下载,安装,设置为Windows服务,启动 2020-06-09
- httpclient 5.0 设置超时时间 2020-05-28
- k8s~fluentd的configmap设置es索引前缀 2020-05-20
- Java 设置PDF中的文本旋转、倾斜 2020-05-11
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash