java.net.socketexception:连接重置

bq9c1y66  于 2021-08-20  发布在  Java
关注(0)|答案(10)|浏览(602)

尝试从套接字读取时出现以下错误。我正在做一件事 readInt() 在那上面 InputStream ,我得到了这个错误。仔细阅读文档,这表明连接的客户端部分关闭了连接。在这个场景中,我是服务器。
我可以访问客户端日志文件,但它没有关闭连接,事实上,它的日志文件表明我正在关闭连接。有人知道为什么会这样吗?还需要检查什么?当本地资源可能达到阈值时,是否会出现这种情况?
我注意到我有以下几行:

socket.setSoTimeout(10000);

就在 readInt() . 这是有原因的(说来话长),但只是好奇,在什么情况下,这可能会导致指示的错误?我让服务器在我的ide中运行,我碰巧让我的ide停留在一个断点上,然后我注意到完全相同的错误开始出现在我自己的ide日志中。
不管怎么说,我只想提一下,希望不是在转移注意力-(

tcomlyy6

tcomlyy61#

有几个可能的原因。
另一端故意重设了连接,我在此不作说明。应用软件很少这样做,而且通常是不正确的,但对于商业软件来说这并不是未知的。
更常见的情况是,它是由于写入另一端已正常关闭的连接而导致的。换句话说,应用程序协议错误。
当套接字接收缓冲区中存在未读数据时,关闭套接字也可能导致此问题。
在windows中,“软件导致的连接中止”与“连接重置”不同,它是由从您的终端发送的网络问题引起的。有一篇关于这方面的微软知识库文章。

8ehkhllq

8ehkhllq2#

连接重置仅仅意味着接收到tcp rst。当您的对等方接收到无法处理的数据时,就会发生这种情况,原因可能多种多样。
最简单的方法是关闭套接字,然后在输出流上写入更多数据。通过关闭插座,您告诉您的同伴您已结束通话,而对方可能会忘记您的连接。无论如何,当您在该流上发送更多数据时,对等方会使用rst拒绝它,以让您知道它没有在侦听。
在其他情况下,介入的防火墙甚至远程主机本身可能“忘记”tcp连接。如果您长时间不发送任何数据(2小时是常见的超时),或者因为对等机重新启动并丢失了有关活动连接的信息,则可能会发生这种情况。在其中一个失效的连接上发送数据也会导致rst。
根据其他信息更新:
仔细看看你对这个问题的处理 SocketTimeoutException . 如果在套接字操作上被阻止时超过了配置的超时,则会引发此异常。当抛出此异常时,套接字本身的状态不会更改,但是如果异常处理程序关闭套接字,然后尝试对其进行写入,则将处于连接重置状态。 setSoTimeout() 是为了给你一个干净的方式来打破 read() 操作,否则可能会永远阻塞,而不会执行诸如从另一个线程关闭套接字之类的肮脏操作。

s1ag04yj

s1ag04yj3#

每当我遇到这种奇怪的问题时,我通常会坐下来使用wireshark之类的工具,查看来回传递的原始数据。您可能会惊讶于事情被断开,并且只有在您尝试阅读时才会收到通知。

n7taea2i

n7taea2i4#

你应该非常仔细地检查整个痕迹,
我有一个服务器套接字应用程序,并修复了一个 java.net.SocketException: Connection reset 案例
在我的例子中,它发生在从clientsocket读取时 Socket 由于某种原因关闭其连接的对象(网络丢失、防火墙或应用程序崩溃或计划关闭)
实际上,当我从这个套接字对象读取数据时出错,我正在重新建立连接。

Socket clientSocket = ServerSocket.accept();
is = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
int readed = is.read(); // WHERE ERROR STARTS !!!

有趣的是 for my JAVA Socket 如果客户端连接到我的 ServerSocket 并在不发送任何内容的情况下关闭其连接 is.read() 正在被重复调用。这似乎是因为处于一个无限while循环中,您试图从一个闭合连接读取此套接字。如果您在读取操作中使用以下内容;

while(true)
{
  Receive();
}

然后你会得到一个像下面这样的堆栈跟踪

java.net.SocketException: Socket is closed
    at java.net.ServerSocket.accept(ServerSocket.java:494)

我所做的只是关闭serversocket并更新连接,等待进一步的客户端连接

String Receive() throws Exception
{
try {                   
            int readed = is.read();
           ....
}catch(Exception e)
{
        tryReConnect();
        logit(); //etc
}

//...
}

这将重新建立未知客户端套接字丢失的连接

private void tryReConnect()
        {
            try
            {
                ServerSocket.close();
                //empty my old lost connection and let it get by garbage col. immediately 
                clientSocket=null;
                System.gc();
                //Wait a new client Socket connection and address this to my local variable
                clientSocket= ServerSocket.accept(); // Waiting for another Connection
                System.out.println("Connection established...");
            }catch (Exception e) {
                String message="ReConnect not successful "+e.getMessage();
                logit();//etc...
            }
        }

我找不到另一种方法,因为正如你们从下图看到的,你们无法理解在没有网络连接的情况下连接是否丢失 try and catch ,因为一切似乎都是对的。我在拍摄照片时拍到了这张快照 Connection reset 连续不断地。

egmofgnx

egmofgnx5#

说起来很尴尬,但当我遇到这个问题时,我只是在读取所有数据之前关闭了连接。在返回小字符串的情况下,它是有效的,但这可能是因为在我关闭它之前,整个响应都被缓冲了。
如果返回的文本量较长,则会引发异常,因为返回的缓冲区比返回的缓冲区多。
你可以检查一下这个疏忽。请记住,打开url就像打开文件一样,请确保在完全读取url后将其关闭(释放连接)。

djmepvbi

djmepvbi6#

我也犯了同样的错误。我现在找到了解决问题的办法。问题是客户端程序在服务器读取流之前完成。

7vhp5slm

7vhp5slm7#

我在用java编写的soa系统中遇到了这个问题。我在不同的物理机器上运行客户机和服务器,它们运行了很长一段时间,然后那些讨厌的连接重置出现在客户机日志中,服务器日志中没有任何奇怪的内容。重新启动客户端和服务器并不能解决问题。最后,我们发现服务器端的堆相当满,所以我们增加了jvm可用的内存:问题解决了!请注意,日志中没有outofmemoryerror:内存不足,没有耗尽。

hkmswyz6

hkmswyz68#

我还遇到了一个java程序试图通过ssh在服务器上发送命令的问题。问题在于机器执行java代码。它没有连接到远程服务器的权限。write()方法运行正常,但是read()方法抛出了一个java.net.socketexception:connection reset。我通过将客户端ssh密钥添加到远程服务器已知密钥中修复了此问题。

bq3bfh9z

bq3bfh9z9#

检查服务器的java版本。发生在我身上是因为我的WebLogic10.3.6在tlsv1上的JDK1.7.0_75上。我尝试使用的rest端点正在关闭tlsv1.2以下的任何内容。
默认情况下,weblogic尝试协商最强的共享协议。请参阅此处的详细信息:设置https连接的https.protocols系统属性的问题。
我添加了详细的ssl日志记录来标识受支持的tls。这表明tlsv1正用于握手。 -Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack 我解决了这个问题,将此功能推出到我们的jdk8兼容产品,jdk8默认为tlsv1.2。对于那些仅限于jdk7的人,我还通过升级到tlsv1.2成功地测试了Java7的一个变通方法。我使用了这个答案:如何在Java7中启用TLS1.2

kiz8lqtg

kiz8lqtg10#

根据我的经验,我经常遇到以下情况:;
如果您在公司工作,请联系网络和安全团队。因为在向外部服务发出的请求中,可能需要为相关端点授予权限。
另一个问题是,运行应用程序的服务器上的ssl证书可能已过期。

相关问题