netty:Connection reset原因

Connection reset

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

异常说明

java.net.SocketException: (Connection reset或者Connect reset by peer:Socket write error)。

  1. 该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个,
  2. 第一个就是如果一端的Socket被关闭(或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。
  3. 另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的

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连接成功)状态,完成三次握手。

除了以上这些常见的标志头信息,还有另外一些标志头信息,比如推标志PSH、复位标志RST等。其中复位标志RST的作用就是“复位相应的TCP连接”。

原因1

服务器关闭了Connection为什么会返回“RST”而不是返回“FIN”标志

  1. 原因在于Socket.close()方法的语义和TCP的“FIN”标志语义不一样:发送TCP的“FIN”标志表示我不再发送数据了,而Socket.close()表示我不在发送也不接受数据了
  2. 问题就出在“我不接受数据” 上,如果此时客户端还往服务器发送数据,服务器内核接收到数据,但是发现此时Socket已经close了,则会返回“RST”标志给客户端。当然,此时客户端就会提示:“Connection reset”

详细说明可以参考oracle的有关文档:http://docs.oracle.com/javase/1.5.0/docs/guide/net/articles/connection_release.html

参考博客

解决方法

我出现的问题是网络原因,网络突然变化出现这种情况
网上搜索了一下,说是有下面的三种解决方法:来源

  1. 出错了重试;
  2. 客户端和服务器统一使用TCP长连接;
  3. 客户端和服务器统一使用TCP短连接。

这篇博客说的非常清楚,也说明如何解析日志,可以参考:https://www.cnblogs.com/shoren/p/httpclient-connectionreset.html

扫描二维码关注公众号,回复: 17239942 查看本文章

猜你喜欢

转载自blog.csdn.net/yyuggjggg/article/details/127857755