官方原因“软件导致连接中止:套接字写入错误”
给定这个堆栈跟踪片段
导致:java.net.SocketException:软件导致连接中止:套接字写入错误
在java.net.SocketOutputStream.socketWrite0(本地方法)
我试图回答以下问题:
- 什么代码抛出这个exception? (JVM?/ Tomcat?/我的代码?)
- 是什么导致这个exception被抛出?
关于#1:
Sun的JVM源不包含这个确切的消息,但我认为文本软件导致连接中止:套接字写入错误是从本地实现SocketOutputStream
:
private native void socketWrite0(FileDescriptor fd, byte[] b, int off, int len) throws IOException;
关于#2
我的猜测是,这是当客户端已经终止连接,在得到完整的响应之前(例如发送请求,但在得到完整的响应之前,它被closures/终止/离线)
问题:
- 上述假设是否正确(#1和#2)?
- 这可以从这种情况分歧:“由于服务器端的networking错误,无法写入客户端”? 或者会呈现相同的错误信息?
- 最重要的是 : 是否有官方文件(例如来自Sun)说明上述情况?
我需要certificate这个堆栈跟踪是套接字客户端的“错误”,并且服务器没有办法避免它。 (除了捕获这个exception,或者使用一个非Sun Java虚拟机的SocketOutputStream,虽然两者都不能真正避免客户端终止的事实)
“当本地networking系统中止连接时,例如WinSock在数据重新传输失败后closures已build立的连接(接收方从不确认在数据stream套接字上发送的数据)时,会发生此错误。” 看到这个MSDN文章 。 另请参阅有关“软件导致连接中止”的一些信息 。
当工作站/笔记本电脑上的企业防火墙挡道时,我经常看到这种情况,它会导致连接中断。
例如。 我在同一台机器上有一个服务器进程和一个客户端进程。 服务器正在监听所有接口(0.0.0.0),并且客户端尝试连接到公共/家庭接口(请注意不是回送接口127.0.0.1)。
如果机器的networking已经断开(例如wificlosures),那么连接就形成了。 如果机器连接到企业networking(直接或vpn),则连接形成。
但是,如果机器连接到公共WiFi(或家庭networking),那么防火墙将杀死连接。 在这种情况下连接客户端到回环接口工作正常,只是没有家庭/公共接口。
希望这可以帮助。
为了certificate哪个组件失败,我将使用wireshark监视TCP / IP通信,并查看谁正在执行closures端口,超时也是相关的。
对于任何使用简单的客户端服务器程序并得到这个错误的人来说,这是一个input或输出stream未closures(或closures到早期)的问题。
你有没有检查过Tomcat源代码和 JVM源代码? 这可能会给你更多的帮助。
我认为你的总体思路是好的。 我期望在无法连接的情况下出现ConnectException
。 上面看起来非常像客户端驱动。
我面临同样的问题。
通常这种错误是由于客户端已经closures了连接,而服务器仍然试图在该客户端上写入。
所以请确保您的客户端连接打开,直到服务器完成其输出stream。
还有一件事,别忘了closuresinput输出stream。
希望这可以帮助。
如果仍然面临的问题比在这里详细介绍你的问题。
当创build或访问套接字 (如TCP )时发生错误时,将引发java.net.SocketException
。 这通常可能是由于服务器终止连接(没有正确closures)造成的,所以在得到完整的响应之前。 在大多数情况下,这可能是由于超时问题(例如响应花费太多时间或者服务器超负荷请求)造成的,或者客户端发送了SYN,但是没有收到ACK(确认连接终止) 。 对于超时问题,可以考虑增加超时值。
套接字exception通常附带有关于该问题的指定详细信息。
详细消息示例:
-
软件导致连接中止:recv失败。
该错误表示尝试发送消息,并且连接已由您的服务器中止。 如果在连接到数据库时发生这种情况,这可能与使用不兼容的Connector / J JDBC驱动程序有关 。
可能的解决scheme:确保在CLASSPATH中有适当的库/驱动程序。
-
导致连接中断的软件:连接。
当连接到远程时出现问题可能会发生这种情况。 例如, 由于病毒检查程序拒绝远程邮件请求 。
可能的解决scheme:检查病毒扫描服务是否阻止传出连接请求的端口。
-
软件导致连接中止:套接字写入错误。
可能的解决scheme:确保你写入正确的字节长度的stream。 所以仔细检查你发送的是什么。 看到这个线程 。
-
由peer重置的连接:套接字写入错误/连接被peer中止:套接字写入错误
应用程序没有检查服务器端的保持连接是否超时。
可能的解决scheme:确保HttpClient在从连接读取之前是非空的。 E13222_01
-
连接由对等重置。
连接已被对等(服务器)终止。
-
连接重置。
由于请求的请求,连接已被客户端终止或被连接的服务器端closures。
请参阅: 什么导致我的java.net.SocketException:连接重置?
这个错误发生在我用SoapUI客户端testing我的soap服务时,基本上我试图得到一个非常大的消息(> 500kb),SoapUI通过超时closures连接。
在SoapUI上:
文件 – >首选项 – 套接字超时(毫秒)
…并把一个很大的价值,如180000(3分钟),这不会是你的问题的完美解决,因为该文件实际上是大,但至less你会有一个回应。
在另一个客户端closures连接
在我的情况下,错误是:
java.net.SocketException: Software caused connection abort: recv failed
它在debugging访问H2数据库的Java应用程序时在eclipse中收到。 错误的根源在于我最初使用SQuirreL打开数据库来手动检查完整性。 我没有使用标志来启用多个连接到相同的数据库(即AUTO_SERVER=TRUE
),所以从java连接到数据库没有问题。
这个错误出现在一段时间之后 – 这是一个很长的java进程 – 我决定closuresSQuirreL来释放资源。 看起来好像SQuirreL是“拥有”数据库服务器实例,并且它是通过SQuirreL连接closures的。
重新启动Java应用程序不会再次产生错误。
configuration
- Windows 7的
- Eclipse开普勒
- SQuirreL 3.6
- org.h2.Driver ver 1.4.192
在下面解释的情况下,客户端会抛出这样的例外:
要求服务器对客户端证书进行身份validation,但客户端提供的证书的“扩展密钥用法”不支持客户端身份validation,因此服务器不接受客户端证书,然后closures连接。
我的服务器在2天内抛出这个exception,我通过移动断开连接function来解决它:
outputStream.close(); inputStream.close(); Client.close();
到列表线程的末尾。 如果它会帮助任何人。
我在使用wireMock模拟其他API调用时遇到了同样的问题。 之前我是这样定义服务器的:
WireMockServer wireMockServer = null;
但是应该像下面这样定义:
@Rule public WireMockRule wireMockRule = new WireMockRule(8089);