java.net.SocketException:连接重置
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/62929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.net.SocketException: Connection reset
提问by
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 this suggests that the client part of the connection closed the connection. In this scenario, I am the server.
尝试从套接字读取时出现以下错误。我做了readInt()
对InputStream
,并且我得到这个错误。仔细阅读文档,这表明连接的客户端部分关闭了连接。在这种情况下,我是服务器。
I have access to the client log files and it is not closing the connection, and in fact 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.
就在readInt()
. 这是有原因的(长篇故事),但只是好奇,是否存在可能导致指示错误的情况?我的服务器在我的 IDE 中运行,我碰巧让我的 IDE 卡在断点上,然后我注意到完全相同的错误开始出现在我自己的 IDE 日志中。
Anyway, just mentioning it, hopefully not a red herring. :-(
无论如何,只是提一下,希望不是红鲱鱼。:-(
回答by GEOCHET
Whenever I have had odd issues like this, I usually sit down with a tool like WireSharkand look at the raw data being passed back and forth. You might be surprised where things are being disconnected, and you are only being notifiedwhen you try and read.
每当我遇到这样的奇怪问题时,我通常会坐下来使用WireShark 之类的工具,查看来回传递的原始数据。您可能会对断开连接的地方感到惊讶,并且只有在您尝试阅读时才会收到通知。
回答by erickson
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.
连接重置只是意味着收到了 TCP RST。当您的对等方接收到它无法处理的数据时会发生这种情况,这可能有多种原因。
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.
最简单的是当你关闭套接字时,然后在输出流上写入更多数据。通过关闭套接字,你告诉你的同伴你已经完成了谈话,它可以忘记你的连接。无论如何,当您在该流上发送更多数据时,对等方会使用 RST 拒绝它,让您知道它没有在侦听。
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.
在其他情况下,干预防火墙甚至远程主机本身可能会“忘记”您的 TCP 连接。如果您长时间不发送任何数据(2 小时是常见的超时),或者因为对等方重新启动并丢失了有关活动连接的信息,则可能会发生这种情况。在这些失效连接之一上发送数据也会导致 RST。
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.
仔细看看你对SocketTimeoutException
. 如果在套接字操作上阻塞时超过配置的超时,则会引发此异常。抛出此异常时,套接字本身的状态不会改变,但如果您的异常处理程序关闭了套接字,然后尝试写入它,您将处于连接重置状态。setSoTimeout()
旨在为您提供一种干净的方法来摆脱read()
可能永远阻塞的操作,而无需做脏事,例如从另一个线程关闭套接字。
回答by user207421
There are several possible causes.
有几种可能的原因。
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.
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.
It can also be caused by closing a socket when there is unread data in the socket receive buffer.
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.
另一端故意重置连接,我不会在这里记录的方式。应用软件这样做的情况很少见,而且通常是不正确的,但对于商业软件来说,这种情况并不陌生。
更常见的是,这是由于写入另一端已经正常关闭的连接引起的。换句话说,应用程序协议错误。
当套接字接收缓冲区中有未读数据时关闭套接字也可能导致此问题。
在 Windows 中,“软件导致连接中止”与“连接重置”不同,是由您端发送的网络问题引起的。有一篇关于此的 Microsoft 知识库文章。
回答by kml_ckr
I had the same error. I found the solution for problem now. The problem was client program was finishing before server read the streams.
我有同样的错误。我现在找到了问题的解决方案。问题是客户端程序在服务器读取流之前完成。
回答by Scott S
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.
你可能会检查这个疏忽。记住打开一个 URL 就像一个文件,一旦它被完全读取,一定要关闭它(释放连接)。
回答by pmartin8
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.
我在尝试通过 SSH 在服务器上发送命令的 Java 程序中也遇到了这个问题。问题出在执行 Java 代码的机器上。它没有连接到远程服务器的权限。write() 方法运行正常,但 read() 方法抛出 java.net.SocketException: Connection reset 。我通过将客户端 SSH 密钥添加到远程服务器已知密钥解决了这个问题。
回答by Pino
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.
我在用 Java 编写的 SOA 系统上遇到了这个问题。我在不同的物理机器上同时运行客户端和服务器,它们长时间工作正常,然后那些讨厌的连接重置出现在客户端日志中,服务器日志中没有任何奇怪的东西。重新启动客户端和服务器并没有解决问题。最后我们发现服务器端的堆已经满了,所以我们增加了 JVM 可用的内存:问题解决了!请注意,日志中没有 OutOfMemoryError:内存只是稀缺,而不是耗尽。
回答by Davut Gürbüz
You should inspect full trace very carefully,
你应该非常仔细地检查完整的跟踪,
I've a server socket application and fixed a java.net.SocketException: Connection reset
case.
我有一个服务器套接字应用程序并修复了一个java.net.SocketException: Connection reset
案例。
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)
在我的情况下,它发生在从Socket
由于某种原因关闭其连接的 clientSocket对象读取时发生。(网络丢失、防火墙或应用程序崩溃或有意关闭)
Actually I was re-establishing connection when I got an error while reading from this Socket object.
实际上,当我从这个 Socket 对象读取时出错时,我正在重新建立连接。
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()
calls itself recursively.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;
有趣的是,for my JAVA Socket
如果客户端连接到我的ServerSocket
并关闭它的连接而不发送任何is.read()
递归调用本身。这似乎是因为在无限循环中从这个套接字读取你试图从关闭的连接读取。如果您使用以下内容进行读取操作;
while(true)
{
Receive();
}
Then you get a stackTrace something like below on and on
然后你会得到一个像下面这样的 stackTrace
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
我所做的只是关闭 ServerSocket 并更新我的连接并等待进一步传入的客户端连接
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.
我找不到另一种方式,因为正如您从下图中看到的,如果没有 a try and catch
,您无法理解连接是否丢失,因为一切似乎都正确。我在Connection reset
不断获得时得到了这张快照。
回答by behold
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.
检查服务器的 Java 版本。发生在我身上是因为我的 Weblogic 10.3.6 在 JDK 1.7.0_75 上,它在 TLSv1 上。我尝试使用的其余端点是关闭 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.
默认情况下,Weblogic 试图协商最强的共享协议。在此处查看详细信息:为 HTTPS 连接设置 https.protocols 系统属性的问题。
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
我添加了详细的 SSL 日志记录来识别支持的 TLS。这表明 TLSv1 用于握手。-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
我通过将该功能推送到我们的 JDK8 兼容产品解决了这个问题,JDK8 默认为 TLSv1.2。对于那些仅限于 JDK7 的人,我还通过升级到 TLSv1.2 成功地测试了 Java 7 的解决方法。我使用了这个答案:如何在 Java 7 中启用 TLS 1.2