java.net.SocketException。连接重置

我在尝试从一个套接字中读取时得到了以下错误。我在那个 "InputStream "上做 "readInt()",但我得到了这个错误。仔细阅读文档,这表明连接的客户端部分关闭了连接。在这种情况下,我是服务器。

我可以访问客户端的日志文件,它没有关闭连接,事实上它的日志文件表明我正在关闭连接。那么,有没有人知道为什么会发生这种情况?还有什么需要检查的吗?当有本地资源可能达到阈值时,会出现这种情况吗?


我确实注意到,我有以下一行。

socket.setSoTimeout(10000);

就在 "readInt() "的前面。这是有原因的(说来话长),但我只是好奇,在什么情况下,这可能会导致上述错误?我在我的IDE中运行服务器,我碰巧让我的IDE卡在一个断点上,然后我注意到我的IDE中的日志开始出现完全相同的错误。

总之,只是提一下,希望不是一个红鲱鱼。

有几个可能的原因。

1.另一端故意重设了连接,我在此不做记录。对于应用软件来说,这样做是很罕见的,而且通常是不正确的,但对于商业软件来说,这并不是没有。

2.2.更常见的是,它是由于向另一端已经正常关闭的连接写入而引起的。换句话说,这是一个应用协议错误。

3.3. 当套接字接收缓冲区中存在未读数据时,关闭套接字也可能造成这种情况。

4.在Windows中,'软件引起的连接中止',与'连接重置'不一样,是由网络问题引起的,从你这端发送。关于这一点,微软有一篇知识库文章。

评论(1)

连接重置只是意味着收到了一个TCP RST。当你的对等体收到它无法处理的数据时,就会发生这种情况,这可能有各种原因。

最简单的是当你关闭套接字,然后在输出流中写入更多数据。通过关闭套接字,你告诉你的对等体你已经谈完了,它可以忘记你的连接。当你在该流上发送更多的数据时,对等体用RST拒绝它,让你知道它没有在听。

在其他情况下,介入的防火墙甚至是远程主机本身都可能忘记你的TCP连接。如果你长时间不发送任何数据(2小时是一个常见的超时),或者因为对等体被重新启动而失去了关于活动连接的信息,就可能发生这种情况。在这些已失效的连接上发送数据也会导致RST。


根据额外的信息进行更新:

仔细看看你对 "SocketTimeoutException "的处理。如果在一个套接字操作被阻塞时超过了配置的超时时间,就会引发这个异常。当这个异常被抛出时,套接字本身的状态并没有改变,但是如果你的异常处理程序关闭了套接字,然后试图向其写入,你就会处于连接重置的状态。setSoTimeout()是为了给你提供一个干净的方法来脱离read()操作,否则可能会永远阻塞,而不会做肮脏的事情,比如从另一个线程关闭套接字。

评论(2)

每当我遇到这样奇怪的问题时,我通常会坐下来用一个像WireShark这样的工具,看一下来回传递的原始数据。你可能会惊讶地发现,有些东西是被断开的,而你只有在试图读取时才会被*通知。

评论(0)