使用httpclient时出现connection reset的问题解决方案

使用httpclient时出现connection reset的问题解决方案

错误如下:

java.net.SocketException: Connection reset
       at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118)
       at java.net.SocketOutputStream.write(SocketOutputStream.java:159)
       at org.apache.http.impl.io.SessionOutputBufferImpl.streamWrite(SessionOutputBufferImpl.java:124)
       at org.apache.http.impl.io.SessionOutputBufferImpl.flushBuffer(SessionOutputBufferImpl.java:136)
       at org.apache.http.impl.io.SessionOutputBufferImpl.write(SessionOutputBufferImpl.java:167)
       at org.apache.http.impl.io.ContentLengthOutputStream.write(ContentLengthOutputStream.java:113)
       at org.apache.http.entity.mime.content.FileBody.writeTo(FileBody.java:121)
       at org.apache.http.entity.mime.AbstractMultipartForm.doWriteTo(AbstractMultipartForm.java:134)
       at org.apache.http.entity.mime.AbstractMultipartForm.writeTo(AbstractMultipartForm.java:157)
       at org.apache.http.entity.mime.MultipartFormEntity.writeTo(MultipartFormEntity.java:113)
       at org.apache.http.impl.DefaultBHttpClientConnection.sendRequestEntity(DefaultBHttpClientConnection.java:156)
       at org.apache.http.impl.conn.CPoolProxy.sendRequestEntity(CPoolProxy.java:162)
       at org.apache.http.protocol.HttpRequestExecutor.doSendRequest(HttpRequestExecutor.java:238)
       at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:123)
       at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:271)
       at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
       at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:88)
       at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)    
       at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)   
       at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
       at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:107)

问题原因:
导致“Connection reset”的原因是服务器端因为某种原因关闭了Connection,而客户端依然在读写数据,此时服务器会返回复位标志“RST”,然后此时客户端就会提示“java.net.SocketException: Connection reset”。

可能有同学对复位标志“RST”还不太了解,这里简单解释一下:

TCP建立连接时需要三次握手,在释放连接需要四次挥手;例如三次握手的过程如下:

第一次握手:客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认;

第二次握手:服务器收到syn包,并会确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
当握手完成,也就意味着创建连接已完成,但是当数据传输完成,服务器一端主动断开连接返回了“RST”时,如果此时客户端正在从Socket套接字的输出流中读数据则会提示Connection reset”;

解决方法:
1. 使用TCP短链接

 httppost.setProtocolVersion(HttpVersion.HTTP_1_0);
 httppost.addHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_CLOSE);

2.设置超时时间

 int timeout = 60;
RequestConfig defaultRequestConfig = RequestConfig.custom()
	.setSocketTimeout(timeout * 1000)
	.setConnectTimeout(timeout * 1000)
	.setConnectionRequestTimeout(timeout * 1000)
	.build();

3.使用 CloseableHttpResponse

CloseableHttpResponse response = null;  
 response = httpClient.execute(httpPost);
 HttpEntity httpEntity = response.getEntity();
 EntityUtils.consume(httpEntity);        //按照官方文档的说法:二者都释放了才可以正常的释放链接
 response.close();
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值