java.io.IOException: Connection reset by peer_心歌技术的博客-程序员秘密

技术标签: 【BUG总结】  

错误信息:

Caused by: java.net.SocketException: Connection reset by peer: socket write error
        at java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111)
        at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
        at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:216)
        at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:487)
        at org.apache.coyote.http11.InternalOutputBuffer.flush(InternalOutputBuffer.java:120)
        at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:828)
        at org.apache.coyote.Response.action(Response.java:173)
        at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:366)
        ... 90 more

错误原因:

从日志中可以看到是Socket套接字在write 数据时抛出了该错误。导致“Connection reset”的原因是服务器端因为某种原因关闭了Connection,而客户端依然在读写数据,此时服务器会返回复位标志“RST”,然后此时客户端就会提示“java.net.SocketException: Connection reset”。

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

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

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

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

  3. 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。

  • 服务器返回了“RST”时,如果此时客户端正在从Socket套接字的输出流中读数据则会提示Connection reset”;

  • 服务器返回了“RST”时,如果此时客户端正在往Socket套接字的输入流中写数据则会提示“Connection reset by peer”。

Socket默认连接60秒,60秒之内没有进行心跳交互,即读写数据,就会自动关闭连接。如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。如果一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。

简单的说就是在连接断开后的读和写操作引起的。

原因1

使用 Java NIO 建立 Socket 服务端,当客户端意外关闭的情况,不是发送指定指令通知服务器退出,就会产生此错误。

原因2

客户端再发起请求后没有等服务器端相应完,点击了stop按钮,导致服务器端接收到取消请求(频繁的刷新就会产生此问题)。通常情况下是不会有这么无聊的用户,出现这种情况可能是由于用户提交了请求,服务器端相应缓慢,比如业务逻辑有问题等原因,导致页面过了很久也没有刷新出来,用户就有可能取消或重新发起请求。 这种错误是合理范围内的,无法避免的,不必关心它。

原因3

Tomcat服务器在接受用户请求的时候,有其自身的处理能力,线程、服务器等各个资源限制,超出Tomcat承载范围的请求,就会被tomcat停掉,也可能产生该错误。服务器的并发连接数超过了其承载量,服务器会将其中一些连接关闭

原因4

Linux的线程机制会产生JVM出错的问题,特别是在连接高峰期间经常出现这样的问题,tomcat在linux下也出现类似情况。

原因5

如果网络连接通过防火墙,而防火墙一般都会有超时的机制,在网络连接长时间不传输数据时,会关闭这个TCP的会话,关闭后在读写,就会导致异常。 如果关闭防火墙,解决了问题,需要重新配置防火墙,或者自己编写程序实现TCP的长连接。实现TCP的长连接,需要自己定义心跳协议,每隔一段时间,发送一次心跳协议,双方维持连接。

解决办法:

1.出错了重试

这种方案可以简单防止“Connection reset”错误,然后如果服务不是“幂等”的则不能使用该方法

2.客户端和服务器统一使用TCP长连接

客户端和服务器统一使用TCP长连接:客户端使用TCP长连接很容易配置(直接设置HttpClient就好),而服务器配置长连接就比较麻烦了,就拿tomcat来说,需要设置tomcat的maxKeepAliveRequests、connectionTimeout等参数。另外如果使用了nginx进行反向代理或负载均衡,此时也需要配置nginx以支持长连接(nginx默认是对客户端使用长连接,对服务器使用短连接)。

使用长连接可以避免每次建立TCP连接的三次握手而节约一定的时间,但是我这边由于是内网,客户端和服务器的3次握手很快,大约只需1ms。ping一下大约0.93ms(一次往返);三次握手也是一次往返(第三次握手不用返回)。根据80/20原理,1ms可以忽略不计;又考虑到长连接的扩展性不如短连接好、修改nginx和tomcat的配置代价很大(所有后台服务都需要修改);所以这里并没有使用长连接。

3.客户端和服务器统一使用TCP短连接

客户端和服务器统一使用TCP短连接:我这边正是这么干的,而使用短连接既不用改nginx配置,也不用改tomcat配置,只需在使用HttpClient时使用http1.0协议并增加http请求的header信息(Connection: Close)

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

 

文章参考:

https://my.oschina.net/xionghui/blog/508758

https://blog.csdn.net/testcs_dn/article/details/78707219

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_23994787/article/details/104246294

智能推荐

iec104协议 java_GitHub - delikely/IEC104_microgrid: iec104协议主站客户端程序,属于微电网管理系统一部分..._一席茶话的博客-程序员秘密

IEC104_microgridiec104协议主站客户端程序,属于微电网管理系统一部分一 IEC104协议介绍1 IEC104简要说明IEC104是一种基于TCP/IP的电力行业通信协议,主要用于数据远程监控等功能。通信有一般有主要发送数据、接收命令的从站服务端和接收数据、发送命令的主站客户端构成。采用应答式数据传输,一般上行数据为遥信、遥测,下行信息为遥控、遥调。2 IEC104帧格式IEC1...

锐捷客户端总是自动关闭VMware NAT Service 解决办法_vmware nat service 自动关闭_scx_white的博客-程序员秘密

解决办法破解版锐捷在宿舍时候我的虚拟机一直用的好好的 ,今天把电脑搬到了实验室就发现虚拟机不能上网了。原因是以桥接模式连接总是显示多个网卡冲突 于是我就修改为NAT模式,可是这种模式还是不能联网 ,查看服务发现VMware NAT Service 服务是关闭 ,打开之后虚拟机能联网了,可是等会这个服务又自动关闭 。想想就是这个流氓锐捷做的,百度了许久也没找到解决办法。 本来想着写个bat脚本注册

IIS上添加处理程序映射wfastcgi_bigcarp的博客-程序员秘密

网上关于IIS部署Django的教程中,添加wfastcgi部分通常只讲如何操作,不讲为什么这样操作,导致个性化的情况不知道如何修改、修改后会有什么后果。一番研究后,做了一些整理。(此文仅包含wfastcgi配置,未包含appSettings等内容)IIS上添加处理程序映射有多种方式,任选一种即可,例如:1、通过pipinstallwfastcgi安装好wfastcgi后,执行wfastcgi-enable。完成IIS全局的映射配置。2、在网站目录下添加 / 编辑 web.co...

洛谷P1363 幻想迷宫[email protected]的博客-程序员秘密

题目描述背景 Background(喵星人LHX和WD同心协力击退了汪星人的入侵,不幸的是,汪星人撤退之前给它们制造了一片幻象迷宫。)WD:呜呜,肿么办啊……LHX:momo…我们一定能走出去的!WD:嗯,+U+U!描述 Description幻象迷宫可以认为是无限大的,不过它由若干个N*M的矩阵重复组成。矩阵中有的地方是道路,用’.‘表示;有的地方是墙,用’#‘表示。LHX和WD所...

cv 边缘检测_dbzr15157的博客-程序员秘密

边缘—>定位&属性测量噪声( 高斯噪声)边缘检测器:3种1. 导数算子Δ1Δ22.模板算子sobel算子Kirsch算子3.数学模型Marr-Hildreth检测器Canny检测器Shen-Castanets(ISEF) 检测器评价检测器的质量:pratt方法kitchen&Rosenfeld方法转载于:https://www.cnblogs.co...

gpio模拟i2c_mars_Vessalius的博客-程序员秘密

gpio模拟i2ci2c写操作I2C读操作i2c写操作I2C协议规定,总线上数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。起始和结束信号总是由主设备产生(意味着从设备不可以主动通信?所有的通信都是主设备发起的,主可以发出询问的command,然后等待从设备的通信)。起始和结束信号产生条件:总线在空闲状态时,SCL和SDA都保持着高电平,当SCL为高电平而SDA由高到低的跳变,表示产生一个起始条件;当SCL为高而SDA由低到高的跳变,表示产生一个停止条件。在起始条件产生后

随便推点

em和rem_deweijuan0194的博客-程序员秘密

em和rem都是相对单位,由浏览器转换为像素值,具体取决于设计中的字体大小设置。1em或者1rem会被浏览器解析成从16px到160px或者其他任意值。em和rem单位之间的区别是浏览器根据谁来转化成px值的。1.emem是相对于被设置元素的font-size的倍数的单位,如图:class sixteen的font-size为16px,则padding:1em...

springboot使用@Value读取不到application.properties中的属性[email protected]' not applicable to constructor_一只小透明的博客-程序员秘密

检查你的配置文件中的配置书写是否正确,如果有的配置书写格式错误的话,即使不是你要读取的属性,也会影响你使用@Value读取配置文件

IPython/Jupyter SQL Magic Functions for PySpark_wshzd的博客-程序员秘密

话题:本文主要讨论使用PySpark 在Jupyter notebooks上使用IPython custom magic functions for running SQLIf you are already famialiar with Apache Spark and Jupyter notebooks may want to go directly to the link

Ubuntu16.04 编译OpenCV 和 Tesseract-OCR_Digital2Slave的博客-程序员秘密

由于最近工作需要将实现的图像识别算法,封装到安卓机器上进行测试。因此,初步考虑在公司Windows 7 旗舰版 64位系统中,利用VirtualBox安装Ubuntu系统;然后,在Ubuntu系统中,编译OpenCV和Tesseract-OCR。 具体步骤如下:一、 安装VirtualBox下载安装VirtualBox安装增强扩展程序VirtualBox 5.1.8 Oracle VM Virt

win10共享文件夹无法访问问题_woodcol的博客-程序员秘密

windows 10因为组策略会造成共享无法访问win + R 键打开运行,或者在开始菜单打开运行,输入gpedit.msc来打开系统组策略,进入”计算机管理” -> “windows设置” -> “安全设置” -> “本地策略” -> “安全选项”,在右边找到“网络访问:本地账户的共享和安全模式”双击这个选项,将内容从”仅来宾”改为”经典”这个就可以在别的电脑上用本机用户登陆了,mac访问wind

Visual Studio基本快捷键_Ruanes的博客-程序员秘密

Code说明ctrl+k+ctrl+c注释ctrl+k+ctrl+u取消注释ctrl+k+ctrl+d代码格式化shift+Del注释ctrl+k+ctrl+c删除行ctrl+F5运行代码F5调试代码F10单步调试,不进入函数内部F11单步调试,进入函数内部...