java.net.SocketException:连接重置

发布于 2024-07-05 22:01:28 字数 493 浏览 11 评论 0原文

我尝试从套接字读取时收到以下错误。 我正在该 InputStream 上执行 readInt(),并且收到此错误。 仔细阅读文档表明连接的客户端部分关闭了连接。 在这个场景中,我是服务器。

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


我确实注意到我有以下行:

socket.setSoTimeout(10000);

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

无论如何,只是提一下,希望不是转移注意力。

I am getting the following error trying to read from a socket. I'm doing a readInt() on that InputStream, and I am getting this error. Perusing the documentation suggests that the client part of the connection closed the connection. In this scenario, I am the server.

I have access to the client log files and it is not closing the connection, and its log files suggest I am closing the connection. So does anybody have an idea why this is happening? What else to check for? Does this arise when there are local resources that are perhaps reaching thresholds?


I do note that I have the following line:

socket.setSoTimeout(10000);

just prior to the readInt(). There is a reason for this (long story), but just curious, are there circumstances under which this might lead to the indicated error? I have the server running in my IDE, and I happened to leave my IDE stuck on a breakpoint, and I then noticed the exact same errors begin appearing in my own logs in my IDE.

Anyway, just mentioning it, hopefully not a red herring.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

花开浅夏 2024-07-12 22:01:28

我在 Java 程序尝试通过 SSH 在服务器上发送命令时也遇到了这个问题。 问题出在执行 Java 代码的机器上。 它没有连接到远程服务器的权限。 write() 方法运行正常,但 read() 方法抛出 java.net.SocketException:连接重置。 我通过将客户端 SSH 密钥添加到远程服务器已知密钥来解决此问题。

I also had this problem with a Java program trying to send a command on a server via SSH. The problem was with the machine executing the Java code. It didn't have the permission to connect to the remote server. The write() method was doing alright, but the read() method was throwing a java.net.SocketException: Connection reset. I fixed this problem with adding the client SSH key to the remote server known keys.

财迷小姐 2024-07-12 22:01:28

连接重置仅仅意味着收到了 TCP RST。 当您的对等方收到它无法处理的数据时,就会发生这种情况,这可能有多种原因。

最简单的是关闭套接字,然后在输出流上写入更多数据。 通过关闭套接字,您告诉您的对等方您已结束通话,并且它可以忘记您的连接。 无论如何,当您在该流上发送更多数据时,对等方会使用 RST 拒绝它,让您知道它没有在监听。

在其他情况下,干预防火墙甚至远程主机本身可能会“忘记”您的 TCP 连接。 如果您长时间不发送任何数据(2 小时是常见的超时),或者因为对等方重新启动并丢失了有关活动连接的信息,则可能会发生这种情况。 在这些失效连接之一上发送数据也会导致 RST。


更新以响应其他信息:

仔细查看您对 SocketTimeoutException 的处理。 如果在套接字操作被阻止时超出配置的超时,则会引发此异常。 抛出此异常时,套接字本身的状态不会更改,但如果异常处理程序关闭套接字,然后尝试写入它,您将处于连接重置状态。 setSoTimeout() 旨在为您提供一种干净的方式来中断 read() 操作,否则该操作可能会永远阻塞,而无需执行诸如从另一个套接字关闭套接字之类的肮脏操作线。

Connection reset simply means that a TCP RST was received. This happens when your peer receives data that it can't process, and there can be various reasons for that.

The simplest is when you close the socket, and then write more data on the output stream. By closing the socket, you told your peer that you are done talking, and it can forget about your connection. When you send more data on that stream anyway, the peer rejects it with an RST to let you know it isn't listening.

In other cases, an intervening firewall or even the remote host itself might "forget" about your TCP connection. This could happen if you don't send any data for a long time (2 hours is a common time-out), or because the peer was rebooted and lost its information about active connections. Sending data on one of these defunct connections will cause a RST too.


Update in response to additional information:

Take a close look at your handling of the SocketTimeoutException. This exception is raised if the configured timeout is exceeded while blocked on a socket operation. The state of the socket itself is not changed when this exception is thrown, but if your exception handler closes the socket, and then tries to write to it, you'll be in a connection reset condition. setSoTimeout() is meant to give you a clean way to break out of a read() operation that might otherwise block forever, without doing dirty things like closing the socket from another thread.

挽清梦 2024-07-12 22:01:28

有几种可能的原因。

  1. 另一端故意重置连接,我不会在此处记录这种方式。 对于应用程序软件来说,这样做的情况很少见,而且通常是不正确的,但对于商业软件来说,这种情况并不陌生。

  2. 更常见的是,这是由于写入另一端已正常关闭的连接而导致的。 换句话说,应用程序协议错误。

  3. 也可能是由于套接字接收缓冲区中有未读数据而关闭套接字造成的。

  4. 在 Windows 中,“软件导致连接中止”与“连接重置”不同,是由您端发送的网络问题引起的。 有一篇关于此问题的 Microsoft 知识库文章。

  5. 如果进程存在但未关闭套接字,则 Windows(但 Unix、Linux 等除外)会重置连接。 其他操作系统正确关闭它。

There are several possible causes.

  1. The other end has deliberately reset the connection, in a way which I will not document here. It is rare, and generally incorrect, for application software to do this, but it is not unknown for commercial software.

  2. More commonly, it is caused by writing to a connection that the other end has already closed normally. In other words an application protocol error.

  3. It can also be caused by closing a socket when there is unread data in the socket receive buffer.

  4. In Windows, 'software caused connection abort', which is not the same as 'connection reset', is caused by network problems sending from your end. There's a Microsoft knowledge base article about this.

  5. Windows, but not Unix, Linux etc., resets a connection if a process exists without closing a socket. The other OSes close it properly.

你在看孤独的风景 2024-07-12 22:01:28

您应该非常仔细地检查完整的跟踪,

我有一个服务器套接字应用程序并修复了 java.net.SocketException:连接重置 情况。

就我而言,它是在从 clientSocket Socket 对象读取数据时发生的,该对象由于某种原因关闭了连接。 (网络丢失、防火墙或应用程序崩溃或有意关闭)

实际上,当我从该 Socket 对象读取时出现错误时,我正在重新建立连接。

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

有趣的是,对于我的 JAVA Socket,如果客户端连接到我的 ServerSocket 并关闭其连接而不发送任何内容,is.read() 正在被执行重复调用。似乎是因为处于无限 while 循环中,因此您尝试从关闭的连接中读取数据。
如果您使用如下所示的内容进行读取操作;

while(true)
{
  Receive();
}

然后你会得到一个类似下面的 stackTrace

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,您将无法了解连接是否丢失,因为一切似乎都是正确的。 我在连续重置连接时得到了这个快照。

输入图像描述这里

You should inspect full trace very carefully,

I've a server socket application and fixed a java.net.SocketException: Connection reset case.

In my case it happens while reading from a clientSocket Socket object which is closed its connection because of some reason. (Network lost,firewall or application crash or intended close)

Actually I was re-establishing connection when I got an error while reading from this Socket object.

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

The interesting thing is for my JAVA Socket if a client connects to my ServerSocket and close its connection without sending anything is.read() is being called repeatedly.It seems because of being in an infinite while loop for reading from this socket you try to read from a closed connection.
If you use something like below for read operation;

while(true)
{
  Receive();
}

Then you get a stackTrace something like below on and on

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

What I did is just closing ServerSocket and renewing my connection and waiting for further incoming client connections

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


//...
}

This reestablises my connection for unknown client socket losts

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...
            }
        }

I couldn't find another way because as you see from below image you can't understand whether connection is lost or not without a try and catch ,because everything seems right . I got this snapshot while I was getting Connection reset continuously.

enter image description here

百善笑为先 2024-07-12 22:01:28

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

Whenever I have had odd issues like this, I usually sit down with a tool like WireShark and look at the raw data being passed back and forth. You might be surprised where things are being disconnected, and you are only being notified when you try and read.

潇烟暮雨 2024-07-12 22:01:28

检查服务器的 Java 版本。 发生在我身上是因为我的 Weblogic 10.3.6 运行在 JDK 1.7.0_75 上,而 JDK 1.7.0_75 运行在 TLSv1 上。 我试图使用的其余端点是关闭 TLSv1.2 以下的任何内容。

默认情况下,Weblogic 尝试协商最强的共享协议。 请参阅此处的详细信息:设置 https.protocols 系统属性的问题用于 HTTPS 连接

我添加了详细的 SSL 日志记录来识别支持的 TLS。 这表明握手使用了 TLSv1。
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

我通过将该功能推送到我们的 JDK8 兼容产品(JDK8 默认值)解决了这个问题到 TLSv1.2。 对于仅限于 JDK7 的用户,我还通过升级到 TLSv1.2 成功测试了 Java 7 的解决方法。 我使用了这个答案:如何在 Java 7 中启用 TLS 1.2< /a>

Check your server's Java version. Happened to me because my Weblogic 10.3.6 was on JDK 1.7.0_75 which was on TLSv1. The rest endpoint I was trying to consume was shutting down anything below TLSv1.2.

By default Weblogic was trying to negotiate the strongest shared protocol. See details here: Issues with setting https.protocols System Property for HTTPS connections.

I added verbose SSL logging to identify the supported TLS. This indicated TLSv1 was being used for the handshake.
-Djavax.net.debug=ssl:handshake:verbose:keymanager:trustmanager -Djava.security.debug=access:stack

I resolved this by pushing the feature out to our JDK8-compatible product, JDK8 defaults to TLSv1.2. For those restricted to JDK7, I also successfully tested a workaround for Java 7 by upgrading to TLSv1.2. I used this answer: How to enable TLS 1.2 in Java 7

烟花肆意 2024-07-12 22:01:28

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

I had the same error. I found the solution for problem now. The problem was client program was finishing before server read the streams.

何时共饮酒 2024-07-12 22:01:28

我在使用 Java 编写的 SOA 系统时遇到了这个问题。 我在不同的物理机器上运行客户端和服务器,并且它们工作了很长一段时间,然后那些令人讨厌的连接重置出现在客户端日志中,而服务器日志中没有任何奇怪的东西。 重新启动客户端和服务器并没有解决问题。 最后我们发现服务器端的堆已经满了,所以我们增加了 JVM 可用的内存:问题解决了! 请注意,日志中没有 OutOfMemoryError:内存只是稀缺,而不是耗尽。

I had this problem with a SOA system written in Java. I was running both the client and the server on different physical machines and they worked fine for a long time, then those nasty connection resets appeared in the client log and there wasn't anything strange in the server log. Restarting both client and server didn't solve the problem. Finally we discovered that the heap on the server side was rather full so we increased the memory available to the JVM: problem solved! Note that there was no OutOfMemoryError in the log: memory was just scarce, not exhausted.

半步萧音过轻尘 2024-07-12 22:01:28

说起来很尴尬,但是当我遇到这个问题时,这只是我在读取所有数据之前关闭连接的错误。 在返回小字符串的情况下,它可以工作,但这可能是因为在我关闭它之前整个响应已被缓冲。

如果返回的文本量较长,则会引发异常,因为返回的文本量超过了缓冲区。

您可以检查一下是否存在这种疏忽。 请记住,打开 URL 就像打开文件一样,一旦完全读取,请务必将其关闭(释放连接)。

Embarrassing to say it, but when I had this problem, it was simply a mistake that I was closing the connection before I read all the data. In cases with small strings being returned, it worked, but that was probably due to the whole response was buffered, before I closed it.

In cases of longer amounts of text being returned, the exception was thrown, since more then a buffer was coming back.

You might check for this oversight. Remember opening a URL is like a file, be sure to close it (release the connection) once it has been fully read.

糖果控 2024-07-12 22:01:28

就我而言,是 DNS 问题
我将解析的 IP 放入主机文件中,一切正常。
当然这不是一个永久的解决方案,这让我有时间解决 DNS 问题。

In my case was DNS problem .
I put in host file the resolved IP and everything works fine.
Of course it is not a permanent solution put this give me time to fix the DNS problem.

陌路终见情 2024-07-12 22:01:28

我还收到 HTTP 500 错误“java.net.SocketException:连接重置”,经过几天的分析,发现问题是由 AWS NAT 网关引起的。 我希望它能帮助某人节省时间并解决问题。

基础设施:

AWS API 网关 (HTTP)、AWS CloudMap、AWS Fargate。

问题调查:

经过深入调查后发现,该问题是由 AWS NAT Gateway 引起的,该网关会将有关特定 NAT 转换的信息保留 350 秒,并在该时间段内没有流量时将其删除。
我的应用程序使用 Java HTTP 客户端,它保持连接 20 分钟。 因此,350 秒后的前 1 或 2 个请求会以 HTTP 500 连接重置结束。 NAT 网关没有有关该特定转换的信息,并且它以 RST 标志进行响应 - 这就是我在日志中看到“连接重置”的原因。

实施的解决方案:

将 HTTP Java 客户端更改为 HTTP Apache 客户端。
HTTP Apache 客户端正确保持连接处于活动状态。
您可以选择调整本机 Java HTTP 客户端以发送 TCP keep-alive,或在 350 秒之前关闭非活动连接。

I was also getting HTTP 500 error "java.net.SocketException: Connection reset", and after couple of days of analyze it turned out that problem is caused by AWS NAT Gateway. I hope it will help someone to save a time and resolve the problem.

Infrastructure:

AWS API Gateway (HTTP), AWS CloudMap, AWS Fargate.

Problem investigation:

After deep investigation it turned out that the problem is caused by AWS NAT Gateway which keeps information about specific NAT translations for 350 sec and removes it if there is no traffic in that period.
My application uses Java HTTP client, which keeps connections for 20 minutes. Due to this, first 1 or 2 requests after time of 350 seconds ends with HTTP 500 Connection Reset. NAT Gateway doesn’t have information about that specific translations and it responds with RST flag - that’s why I saw “Connection Reset” in logs.

Implemented solution:

Changing HTTP Java client to HTTP Apache client.
HTTP Apache client properly keeps connection alive.
Optionally you can adjust native Java HTTP client to send TCP keep-alive, or to close inactive connection earlier than 350sec.

深海蓝天 2024-07-12 22:01:28

根据我的经验,我经常遇到以下情况;

  1. 如果您在企业公司工作,请联系网络和安全团队。 因为在向外部服务发出请求时,可能需要授予相关端点的权限。

  2. 另一个问题是服务器上的SSL 证书可能已过期运行应用程序的服务器。

In my experience, I often encounter the following situations;

  1. If you work in a corporate company, contact the network and security team. Because in requests made to external services, it may be necessary to give permission for the relevant endpoint.

  2. Another issue is that the SSL certificate may have expired on the server where your application is running.

瞳孔里扚悲伤 2024-07-12 22:01:28

总的来说,为了找到问题的根本原因,我发现使用 tcpdump 等工具跟踪传入/传出的 tcp 数据包很有帮助。
我发现这篇文章有助于通过实际会话展示 连接重置问题(使用示例重现器)。

Overall, to find the root cause of the issue, I've found helpful to trace incoming/outgoing tcp packets with a tool such as tcpdump.
I've found this article useful to show through a real session the detection of the root cause of the Connection Reset Issue by using a sample reproducer.

无悔心 2024-07-12 22:01:28

我遇到过类似的套接字异常。 我们设置了一个 MFT SFTP 连接,其中包含两个连续的 control-m 作业,每个作业向外部服务器发送 10 个 1Mo 文件,每个文件持续 1 分钟。 有时,外部服务器上缺少文件,MFT 日志中出现以下错误:

Error writing data to final destination. | Proxy error in reading file.
(...)
Failed to connect to ssh server. Exception: java.net.SocketTimeoutException

我们通过在两个 control-m 作业的调度之间添加 2 分钟的延迟来修复此异常。

I've encountered a similar socket exception. We've setup an MFT SFTP connection with two sequential control-m jobs each sending 10 files of 1Mo each for 1 minute to an external server. Sometimes, a file was missing on the external server with the following error in our MFT logs:

Error writing data to final destination. | Proxy error in reading file.
(...)
Failed to connect to ssh server. Exception: java.net.SocketTimeoutException

We fixed this anomaly by adding a 2 minutes delay between the scheduling of the two control-m jobs.

八巷 2024-07-12 22:01:28

我曾经在 Netbeans7.4 设置的 Apache 控制台中收到“NotifyUtil::java.net.SocketException: Connection Reset at java.net.SocketInputStream.read(SocketInputStream.java:...”消息。

我尝试了很多解决方案为了摆脱这个问题,对我有用的是在 Tomcat 上启用 TLS,

具体方法如下:

创建一个密钥库文件来存储服务器的私钥和
通过执行以下命令来获得自签名证书:

Windows:

“%JAVA_HOME%\bin\keytool”-genkey -alias tomcat -keyalg RSA

Unix:

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA

并指定密码值“changeit”。

根据 https://tomcat.apache.org/tomcat-7.0- doc/ssl-howto.html
(这将在您的本地用户目录中创建一个 .keystore 文件)

然后编辑 server.xml (取消注释并编辑相关行)文件 (%CATALINA_HOME%apache-tomcat-7.0.41.0_base\conf\server.xml) 以启用 SSL 和 TLS协议:

 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                maxThreads="150" scheme="https" secure="true"
                clientAuth="false" sslProtocol="TLS" keystorePass="changeit" />

我希望这有帮助

I used to get the 'NotifyUtil::java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:...' message in the Apache Console of my Netbeans7.4 setup.

I tried many solutions to get away from it, what worked for me is enabling the TLS on Tomcat.

Here is how to:

Create a keystore file to store the server's private key and
self-signed certificate by executing the following command:

Windows:

"%JAVA_HOME%\bin\keytool" -genkey -alias tomcat -keyalg RSA

Unix:

$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA

and specify a password value of "changeit".

As per https://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html
(This will create a .keystore file in your localuser dir)

Then edit server.xml (uncomment and edit relevant lines) file (%CATALINA_HOME%apache-tomcat-7.0.41.0_base\conf\server.xml) to enable SSL and TLS protocol:

 <Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
                maxThreads="150" scheme="https" secure="true"
                clientAuth="false" sslProtocol="TLS" keystorePass="changeit" />

I hope this helps

七色彩虹 2024-07-12 22:01:28

我见过这个问题。 就我而言,由于在特定 Java 类中重用相同的 ClientRequest 对象而导致错误。 该项目正在使用 Jboss Resteasy

  1. 最初只有一种方法是使用/调用对象 ClientRequest(作为类中的全局变量放置)来执行特定 URL 中的请求。
  2. 之后,创建了另一个方法来通过另一个 URL 获取数据,但重用了相同的 ClientRequest 对象。

解决方案:在同一个类中创建另一个 ClientRequest 对象,并且专门不重复使用。

I've seen this problem. In my case, there was an error caused by reusing the same ClientRequest object in an specific Java class. That project was using Jboss Resteasy.

  1. Initially only one method was using/invoking the object ClientRequest (placed as global variable in the class) to do a request in an specific URL.
  2. After that, another method was created to get data with another URL, reusing the same ClientRequest object, though.

The solution: in the same class was created another ClientRequest object and exclusively to not be reused.

oО清风挽发oО 2024-07-12 22:01:28

就我而言,这是 TSL 版本的问题。 我正在使用带有 OkHttp 客户端的 Retrofit,在服务器端更新 ALB 后,我应该删除带有 connectionSpecs 的配置:

OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        List<ConnectionSpec> connectionSpecs = new ArrayList<>();
        connectionSpecs.add(ConnectionSpec.COMPATIBLE_TLS);
  //      clientBuilder.connectionSpecs(connectionSpecs);

因此尝试删除或添加此配置以使用不同的 TSL 配置。

In my case it was problem with TSL version. I was using Retrofit with OkHttp client and after update ALB on server side I should have to delete my config with connectionSpecs:

OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        List<ConnectionSpec> connectionSpecs = new ArrayList<>();
        connectionSpecs.add(ConnectionSpec.COMPATIBLE_TLS);
  //      clientBuilder.connectionSpecs(connectionSpecs);

So try to remove or add this config to use different TSL configurations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文