“软件导致连接中止:套接字写入错误”的官方原因
鉴于此堆栈跟踪片段
由以下原因引起:java.net.SocketException: 软件导致连接中止: 套接字写入错误
at java.net.SocketOutputStream.socketWrite0(本机 方法)
我尝试回答以下问题:
- 什么代码抛出此异常? (JVM?/Tomcat?/我的代码?)
- 什么原因导致抛出此异常?
关于#1:
Sun 的 JVM 源代码不包含这个确切的消息,但我认为文本软件导致连接中止:套接字写入错误来自的本机实现>SocketOutputStream
:
private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
int len) throws IOException;
关于#2
我的猜测是,它是在客户端在获得完整响应之前终止连接时引起的(例如发送了一个请求,但在获得完整响应之前,它已关闭/终止/离线)
问题:
- 上述假设是否正确(#1 和 #2)?
- 这可以与“由于服务器端的网络错误而无法写入客户端”的情况区分开来吗?或者会呈现相同的错误消息?
- 最重要的是:是否有官方文档(例如来自 Sun)说明上述内容?
我需要证明该堆栈跟踪是套接字客户端的“错误”,并且服务器没有任何错误本可以避免它。 (除了捕获异常或使用非 Sun JVM SocketOutputStream,尽管两者都不能真正避免客户端已终止的事实)
Given this stack trace snippet
Caused by: java.net.SocketException:
Software caused connection abort:
socket write error
at
java.net.SocketOutputStream.socketWrite0(Native
Method)
I tried to answer the following questions:
- What code is throwing this exception? (JVM?/Tomcat?/My code?)
- What causes this exception to be thrown?
Regarding #1:
Sun's JVM source doesn't contain this exact message, but I think the text Software caused connection abort: socket write error is from the native implementation of SocketOutputStream
:
private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
int len) throws IOException;
Regarding #2
My guess is that it is caused when the client has terminated the connection, before getting the full response (e.g. sent a request, but before getting the full response, it got closed / terminated / offline)
Questions:
- Are the above assumptions correct (#1 and #2)?
- Can this be diffrentiated from the situation: "could not write to the client, due to a network error on the server side"? or would that render the same error message?
- And most important: Is there an official document (e.g from Sun) stating the above?
I need to have a proof that this stack trace is the socket client's "fault", and there is nothing that the server could have done to avoid it. (except catching the exception, or using a non Sun JVM SocketOutputStream, though both don't really avoid the fact the client has terminated)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(14)
请参阅这篇 MSDN 文章。另请参阅有关“软件导致连接中止”的一些信息。
See this MSDN article. See also Some information about 'Software caused connection abort'.
java.net.SocketException
当创建或访问套接字(例如TCP)。这通常是在服务器终止连接(没有正确关闭它)、因此在获得完整响应之前引起的。在大多数情况下,这可能是由于超时问题(例如,响应花费太多时间或服务器因请求而过载)引起的,或者客户端发送了 SYN,但没有收到 ACK(连接终止的确认) 。对于超时问题,可以考虑增加超时值。套接字异常通常附带有关该问题的指定详细消息。
详细消息示例:
软件导致连接中止:连接。
当连接到遥控器时出现问题时,可能会发生这种情况。例如由于病毒检查程序拒绝远程邮件请求< /a>.
可能的解决方案:检查病毒扫描服务是否阻止了传出连接请求的端口。
软件导致连接中止:套接字写入错误。
可能的解决方案:确保将正确长度的字节写入流。因此,请仔细检查您发送的内容。请参阅此主题。
连接被对等方重置:套接字写入错误/连接被对等方中止:套接字写入错误
应用程序未检查服务器端的 keep-alive 连接是否超时。
可能的解决方案:从连接读取之前确保 HttpClient 不为空。E13222_01
连接重置。
由于请求的请求,连接已被客户端终止或被连接的服务器端关闭。
请参阅:是什么导致了我的 java.net.SocketException:连接重置?
The
java.net.SocketException
is thrown when there is an error creating or accessing a socket (such as TCP). This usually can be caused when the server has terminated the connection (without properly closing it), so before getting the full response. In most cases this can be caused either by the timeout issue (e.g. the response takes too much time or server is overloaded with the requests), or the client sent the SYN, but it didn't receive ACK (acknowledgment of the connection termination). For timeout issues, you can consider increasing the timeout value.The Socket Exception usually comes with the specified detail message about the issue.
Example of detailed messages:
The error indicates an attempt to send the message and the connection has been aborted by your server. If this happened while connecting to the database, this can be related to using not compatible Connector/J JDBC driver.
Possible solution: Make sure you've proper libraries/drivers in your CLASSPATH.
This can happen when there is a problem to connect to the remote. For example due to virus-checker rejecting the remote mail requests.
Possible solution: Check Virus scan service whether it's blocking the port for the outgoing requests for connections.
Possible solution: Make sure you're writing the correct length of bytes to the stream. So double check what you're sending. See this thread.
The application did not check whether keep-alive connection had been timed out on the server side.
Possible solution: Ensure that the HttpClient is non-null before reading from the connection.E13222_01
The connection has been terminated by the peer (server).
The connection has been either terminated by the client or closed by the server end of the connection due to request with the request.
See: What's causing my java.net.SocketException: Connection reset?
当工作站/笔记本电脑上的公司防火墙妨碍时,我最常看到这种情况,它会终止连接。
例如。我在同一台机器上有一个服务器进程和一个客户端进程。服务器正在侦听所有接口 (0.0.0.0),并且客户端尝试连接到公共/家庭接口(注意不是环回接口 127.0.0.1)。
如果机器的网络已断开(例如,wifi 已关闭),则会形成连接。如果计算机连接到公司网络(直接或 VPN),则会形成连接。
但是,如果机器连接到公共 WiFi(或家庭网络),则防火墙会启动并终止连接。在这种情况下,将客户端连接到环回接口可以正常工作,只是不能连接到家庭/公共接口。
希望这有帮助。
I have seen this most often when a corporate firewall on a workstation/laptop gets in the way, it kills the connection.
eg. I have a server process and a client process on the same machine. The server is listening on all interfaces (0.0.0.0) and the client attempts a connection to the public/home interface (note not the loopback interface 127.0.0.1).
If the machine is has its network disconnected (eg wifi turned off) then the connection is formed. If the machine is connected to the corporate network (directly or vpn) then the connection is formed.
However, if the machine is connected to a public wifi (or home network) then the firewall kicks in an kills the connection. In this situation connecting the client to the loopback interface works fine, just not to the home/public interface.
Hope this helps.
为了证明哪个组件发生故障,我将使用 wireshark 监视 TCP/IP 通信,并查看谁实际上关闭了端口,超时也可能相关。
To prove which component fails I would monitor the TCP/IP communication using wireshark and look who is actaully closing the port, also timeouts could be relevant.
对于任何使用简单的客户端服务器程序并收到此错误的人来说,这是未关闭(或早期关闭)输入或输出流的问题。
For anyone using simple Client Server programms and getting this error, it is a problem of unclosed (or closed to early) Input or Output Streams.
尽管将正确的证书导入到 cacerts trustore,但 SSLPoke.bat(SSL 故障排除脚本)窗口脚本仍出现此错误。
然后我检查了一些关于我工作中的一些网络变化的旧笔记。我们会
某些情况下需要添加JVM参数
-Djava.net.preferIPv4Stack=true 与某些机器建立连接
在我们的网络中以避免此错误。
连接成功
SSLPoke 的代码可以从这里下载:
https://gist.github.com/4ndrej/4547029
Had an SSLPoke.bat (SSL troubleshooting script) window script that was getting this error despite importing the correct certificates into the cacerts trustore.
I then checked some old notes about some network changes at my job. We would
need in some cases to add the JVM parameter
-Djava.net.preferIPv4Stack=true to make connections to certain machines
in our network to avoid this error.
Successfully connected
The code for SSLPoke can be downloaded from here:
https://gist.github.com/4ndrej/4547029
您检查过 Tomcat 源代码和 JVM 源代码吗?这可能会给你更多帮助。
我认为你的总体想法是好的。我希望在无法连接的情况下出现
ConnectException
。上面看起来很像是客户端驱动的。Have you checked the Tomcat source code and the JVM source ? That may give you more help.
I think your general thinking is good. I would expect a
ConnectException
in the scenario that you couldn't connect. The above looks very like it's client-driven.我也面临着同样的问题。
通常发生这种错误是由于客户端已关闭其连接而服务器仍在尝试在该客户端上写入。
因此,请确保您的客户端已打开连接,直到服务器完成其输出流。
还有一件事,不要忘记关闭输入和输出流。
希望这会有所帮助。
如果仍然面临问题,请在此处详细介绍您的问题。
I was facing the same issue.
Commonly This kind of error occurs due to client has closed its connection and server still trying to write on that client.
So make sure that your client has its connection open until server done with its outputstream.
And one more thing, Don`t forgot to close input and output stream.
Hope this helps.
And if still facing issue than brief your problem here in details.
我在使用 SoapUI 客户端测试我的肥皂服务时发生了这个错误,基本上我试图获取一条非常大的消息(> 500kb),并且 SoapUI 通过超时关闭了连接。
...并输入一个较大的值,例如 180000(3 分钟),这不会是您问题的完美解决方案,因为该文件是其实很大,但至少你会有回应。
This error happened to me while testing my soap service with SoapUI client, basically I was trying to get a very big message (>500kb) and SoapUI closed the connection by timeout.
...and put a large value, such as 180000 (3 minutes), this won't be the perfect fix for your issue because the file is in fact to large, but at least you will have a response.
另一个客户端中的关闭连接
在我的例子中,错误是:
在调试访问 H2 数据库的 java 应用程序时在 eclipse 中收到它。错误的根源是我最初使用 SQuirreL 打开数据库来手动检查完整性。我确实使用该标志启用了与同一数据库的多个连接(即
AUTO_SERVER=TRUE
),因此从 java 连接到数据库没有问题。过了一段时间——这是一个很长的java进程——我决定关闭SQuirreL以释放资源时,出现了错误。看起来好像 SQuirreL 是数据库服务器实例的“拥有者”,并且该实例已随 SQuirreL 连接而关闭。
重新启动 Java 应用程序并没有再次产生该错误。
配置
Closed connection in another client
In my case, the error was:
It was received in eclipse while debugging a java application accessing a H2 database. The source of the error was that I had initially opened the database with SQuirreL to check manually for integrity. I did use the flag to enable multiple connections to the same DB (i.e.
AUTO_SERVER=TRUE
), so there was no problem connecting to the DB from java.The error appeared when, after a while --it is a long java process-- I decided to close SQuirreL to free resources. It appears as if SQuirreL were the one "owning" the DB server instance and that it was shut down with the SQuirreL connection.
Restarting the Java application did not yield the error again.
config
在下面解释的情况下,客户端会抛出这样的异常:
服务器被要求验证客户端证书,但客户端提供的证书扩展密钥用法不支持客户端身份验证,因此服务器不接受客户端的证书,然后关闭连接。
In the situation explained below, client side will throw such an exception:
The server is asked to authenticate client certificate, but the client provides a certificate which Extended Key Usage doesn't support client auth, so the server doesn't accept the client's certificate, and then it closes the connection.
我的服务器在过去的两天内抛出了这个异常,我通过将断开连接功能移动到
列表线程的末尾来解决它。
如果它对任何人有帮助的话。
My server was throwing this exception in the pass 2 days and I solved it by moving the disconnecting function with:
To the end of the listing thread.
if it will helped anyone.
就我而言,我开发了客户端和服务器端,但有一个例外:
当客户端和服务器中的类不同时 。我不在客户端上下载服务器的类(接口),我只是在项目中添加相同的文件。
但路径必须完全相同。
例如,在服务器项目上,我有 java\rmi\services 包,其中包含一些 serviceInterface 和实现,我必须在客户端项目上创建相同的包。例如,如果我通过 java/rmi/server/services 更改它,我会得到上述异常。
如果客户端和服务器之间的接口版本不同(即使无意中添加了一个空行...我认为 rmi 会进行某种类的哈希来检查版本...我不知道...
如果它可以帮助...
In my case, I developped the client and the server side, and I have the exception :
when classes in client and server are different. I don't download server's classes (Interfaces) on the client, I juste add same files in the project.
But the path must be exactly the same.
For example, on the server project I have java\rmi\services packages with some serviceInterface and implementations, I have to create the same package on the client project. If I change it by java/rmi/server/services for example, I get the above exception.
Same exception if the interface version is different between client and server (even with an empty row added inadvertently ... I think rmi makes a sort of hash of classes to check version ... I don't know...
If it could help ...
在模拟其余 API 调用时,我在使用wireMock 时遇到了同样的问题。
之前我是这样定义服务器的:
但它应该如下定义:
I was facing the same problem with wireMock while mocking the rest API calls.
Earlier I was defining the server like this:
But it should be defined like as shown below: