“软件导致连接中止:套接字写入错误”的官方原因

Official reasons for "Software caused connection abort: socket write error"

提问人:Eran Medan 提问时间:1/24/2010 更新时间:10/28/2021 访问量:410287

问:

给定此堆栈跟踪代码片段

引起原因:java.net.SocketException: 软件导致连接中止: 套接字写入错误
java.net.SocketOutputStream.socketWrite0(本机 方法)

我试图回答以下问题:

  1. 是什么代码引发了此异常?(JVM?/Tomcat?/我的代码?)
  2. 是什么原因导致引发此异常?

关于#1:

Sun 的 JVM 源代码不包含此确切消息,但我认为文本 Software caused connection abort: socket write error 来自以下本机实现:SocketOutputStream

private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
                 int len) throws IOException;

关于#2

我的猜测是,这是在客户端终止连接时引起的,在获得完整响应之前(例如,发送请求,但在获得完整响应之前,它被关闭/终止/脱机)

问题:

  1. 上述假设是否正确(#1 和 #2)?
  2. 这是否可以与以下情况区分开来:“由于服务器端的网络错误,无法写入客户端”?或者这会呈现相同的错误消息吗?
  3. 最重要的是:是否有官方文件(例如来自Sun)说明上述内容?

我需要证明这个堆栈跟踪是套接字客户端的“错误”,并且服务器无法采取任何措施来避免它。(除了捕获异常或使用非 Sun JVM SocketOutputStream,尽管两者都不能真正避免客户端已终止的事实)

Java 异常 套接字 Tomcat 堆栈跟踪

评论

0赞 koppor 10/26/2013
我在使用Firefox取消下载时遇到了这个问题
0赞 Amogh 3/10/2015
嘿 Eran,我在发送/写入 () 时也遇到此异常。当音频播放时,如果用户单击任何其他菜单(发送服务器请求),我在控制台上遇到了同样的错误。那么忽略这个例外是否安全呢?outs.write(audioBytes);byte[]OutputStream
1赞 Eran Medan 3/11/2015
@Amogh - 似乎是这样,是的。基本上从答案所描述的内容来看,这是一个特定于 Windows 的错误,但我假设在 Linux 上您会得到相同的异常,只是措辞不同......(我的外行术语对它的理解基本上是,这是当您通过套接字发送到某个远程位置 X 并且 X 在中间断开连接时引起的,但我敢肯定这不是最准确的描述方式)
1赞 Kshitiz Sharma 2/16/2017
对我来说,这发生在数据库服务器重新启动并且应用程序仍在尝试使用先前打开的连接进行查询时。不知道为什么这些没有刷新,因为我们使用的是基于 DBCP 的池。但是重新启动应用程序解决了这个问题。

答:

1赞 Brian Agnew 1/24/2010 #1

您是否检查过 Tomcat 源代码 JVM 源代码?这可能会给你更多的帮助。

我认为你的总体想法很好。我希望在您无法连接的情况下。上面看起来很像是客户端驱动的。ConnectException

评论

3赞 Eran Medan 1/24/2010
是的,我已经检查过了。Tomcat 的来源不包含任何句子的排列,谢谢。
1赞 Stephen C 1/24/2010
不,他没有检查 Tomcat 源代码 JVM 源代码。
0赞 Stephen C 1/24/2010
或者,如果他检查了 JVM 源代码,他并没有检查所有源代码。
1赞 Stephen C 1/27/2010
@Ehrann - 消息字符串很可能在本机源中。但您还应该检查事件日志。IMO,后者可能提供更多信息。
7赞 user207421 10/13/2011
此消息字符串实际上来自操作系统。
4赞 stacker 1/24/2010 #2

为了证明哪个组件失败,我将使用 wireshark 监控 TCP/IP 通信,并查看谁实际上关闭了端口,超时也可能是相关的。

评论

0赞 user207421 11/19/2014
没有人关闭港口。操作系统正在中止连接。
0赞 Zee 4/11/2015
@EJP 我已经看到当过载并内存不足时会发生这种情况。我不确定是操作系统关闭了连接,但 JVM 变得疯狂。
1赞 user207421 5/27/2015
@Zee 关闭端口(在 Wireshark 中显示为 FIN)和中止连接(并非如此)是有区别的。
57赞 user207421 10/13/2011 #3

当本地网络系统中止 连接,例如当 WinSock 关闭已建立的连接时 数据重新传输失败后(接收方从不确认已发送的数据 在数据流套接字上)。

请参阅此 MSDN 文章。另请参阅有关“软件导致的连接中止”的一些信息

评论

3赞 user207421 12/5/2012
@MatGessel 那篇文章只是重复了这种混淆,并添加了一些自己的内容。WSAECONNABORTED 是 Winsock 错误代码,因此不可能有伯克利的解释。所描述的有关 HTTP 服务器的情况将产生 ECONNRESET,而不是 WSAECONNABORTED。
1赞 user207421 5/27/2015
@rustyx 这里引用的所有三个来源都指出它是由 ACK 故障产生的。如果您有自己的主张来源,请引用它。
3赞 Derek Bennett 3/20/2017
这不是一个真正的答案,因为它没有为您提供进一步解决问题的信息。这里的答案基本上是“网络上发生了一些不好的事情”。了解哪些进一步的日志和其他活动记录可以让我查明潜在的问题,这将是非常有帮助的。
1赞 user207421 3/21/2017
@DerekBennet 本答复中说明了根本问题。你的评论令人费解。
11赞 user2028913 1/31/2013 #4

我最常看到这种情况,当工作站/笔记本电脑上的公司防火墙妨碍时,它会终止连接。

例如。我在同一台机器上有一个服务器进程和一个客户端进程。服务器正在侦听所有接口 (0.0.0.0),客户端尝试连接到公共/主接口(注意不是环回接口 127.0.0.1)。

如果机器的网络断开(例如 wifi 关闭),则形成连接。如果计算机连接到公司网络(直接或 vpn),则形成连接。

但是,如果机器连接到公共 wifi(或家庭网络),则防火墙会启动并终止连接。在这种情况下,将客户端连接到环回接口工作正常,只是不能连接到家庭/公共接口。

希望这会有所帮助。

评论

3赞 user207421 7/23/2016
防火墙阻止连接。问题是关于重置现有连接。
3赞 PRO_gramista 11/25/2014 #5

对于使用简单客户端服务器程序并收到此错误的任何人,这是未关闭(或提前关闭)输入或输出流的问题。

评论

3赞 user207421 5/27/2015
不,不是。这将构成插座泄漏,最终导致 FD 耗尽。
-1赞 Sefi Erlich 9/27/2015 #6

我的服务器在过去 2 天内抛出了这个异常,我通过移动断开连接功能解决了它:

outputStream.close();
inputStream.close();
Client.close();

到列表线程的末尾。 如果它能帮助任何人。

1赞 Nirav Chhatrola 6/28/2016 #7

我面临着同样的问题。
通常,由于客户端已关闭其连接,并且服务器仍在尝试在该客户端上写入,因此会发生此类错误。
因此,请确保您的客户端已打开其连接,直到服务器完成其输出流。
还有一件事,不要忘记关闭输入和输出流。

希望这会有所帮助。
如果仍然面临问题,请在此处详细介绍您的问题。

评论

3赞 user207421 7/4/2017
@BhavinChhatrola 不,一个不正确的答案。所描述的情况会产生“对等方重置连接”,而不是问题中的错误。
16赞 kenorb 8/25/2016 #8

当创建或访问套接字(例如 TCP)时出错时,将引发 java.net.SocketException。这通常是在服务器终止连接(没有正确关闭连接)时导致的,因此在获得完整响应之前。在大多数情况下,这可能是由超时问题引起的(例如,响应花费太多时间或服务器因请求过载),或者客户端发送了 SYN,但它没有收到 ACK(确认连接终止)。对于超时问题,可以考虑增加超时值。

套接字异常通常附带有关问题的指定详细信息消息。

详细消息示例:

  • 软件导致连接中止:recv 失败。

    该错误表示尝试发送消息,并且服务器已中止连接。如果在连接到数据库时发生这种情况,这可能与使用不兼容的 Connector/J JDBC 驱动程序有关。

    可能的解决方案:确保 CLASSPATH 中有适当的库/驱动程序。

  • 软件导致连接中止:连接。

    当连接到遥控器出现问题时,可能会发生这种情况。例如,由于病毒检查器拒绝远程邮件请求

    可能的解决方案:检查病毒扫描服务是否阻止了传出连接请求的端口。

  • 软件导致连接中止:套接字写入错误。

    可能的解决方案:确保将正确的字节长度写入流。因此,请仔细检查您发送的内容。请参阅此线程

  • 对等方重置连接:套接字写入错误/对等方中止连接:套接字写入错误

    应用程序未检查服务器端的保持连接是否超时。

    可能的解决方案:在从连接读取之前,请确保 HttpClient 为非 null。E13222_01

  • 连接由对等方重置。

    对等方(服务器)已终止连接。

  • 连接重置。

    由于请求与请求,连接已被客户端终止或由连接的服务器端关闭。

    请参见:是什么导致了我的 java.net.SocketException:连接重置?

评论

0赞 user207421 7/4/2017
这 6 点中只有一点实际上错误地回答了问题。其他几个也是不正确的。应用程序无法“检查服务器端的保持连接是否超时”。存在不可能导致 .没有将正确的长度写入流也不会。HttpClientnullSocketException
0赞 Marco 9/22/2016 #9

在使用 SoapUI 客户端测试我的 soap 服务时,这个错误发生在我身上,基本上我试图获得一个非常大的消息 (>500kb),而 SoapUI 通过超时关闭了连接。

在 SoapUI 上,转到:

文件-->首选项--套接字超时(毫秒)

...并放置一个较大的值,例如 180000(3 分钟),这并不是解决您问题的完美方法,因为文件实际上很大,但至少您会得到响应。

-3赞 Yallaling Goudar 12/1/2016 #10

我在模拟其余 API 调用时遇到了 wireMock 的相同问题。 之前我是这样定义服务器的:

WireMockServer wireMockServer = null;

但它应该如下图所示:

@Rule 
public WireMockRule wireMockRule = new WireMockRule(8089);

评论

0赞 user207421 7/4/2017
那将导致 ,而不是这个问题。NullPointerException
0赞 manuelvigarcia 2/23/2017 #11

另一个客户端中的已关闭连接

就我而言,错误是:

java.net.SocketException: Software caused connection abort: recv failed

它是在 eclipse 中调试访问 H2 数据库的 java 应用程序时收到的。错误的根源是我最初使用 SQuirreL 打开数据库以手动检查完整性。我确实使用该标志来启用与同一数据库的多个连接(即 ),因此从 java 连接到数据库没有问题。AUTO_SERVER=TRUE

过了一会儿,这个错误出现了——这是一个漫长的 java 过程——我决定关闭 SQuirreL 以释放资源。看起来好像 SQuirreL 是“拥有”数据库服务器实例的人,并且它已通过 SQuirreL 连接关闭。

重新启动 Java 应用程序不会再次产生错误。

配置

  • 视窗 7
  • 日食开普勒
  • SQuirreL 3.6
  • org.h2.驱动程序版本 1.4.192
0赞 xiaoming 10/13/2017 #12

在下面解释的情况下,客户端将抛出这样的异常:

要求服务器对客户端证书进行身份验证,但客户端提供的证书扩展密钥用法不支持客户端身份验证,因此服务器不接受客户端的证书,然后关闭连接。

评论

0赞 President James K. Polk 5/16/2018
这个答案是不正确的。在您描述的情况下,将抛出 SSLException。
1赞 xiaoming 3/28/2019
实际上它抛出的 SocketException 就像当前的问题一样,我已经测试过了
-1赞 Elloco 12/20/2019 #13

就我而言,我开发了客户端和服务器端,但有例外:

原因:错误封送参数;嵌套异常为: java.net.SocketException:软件导致连接中止:套接字 写入错误

当客户端和服务器中的类不同时。我不在客户端上下载服务器的类(接口),我只是在项目中添加相同的文件。 但路径必须完全相同。 例如,在服务器项目上,我有带有一些 serviceInterface 和实现的 java\rmi\services 包,我必须在客户端项目上创建相同的包。例如,如果我通过java / rmi / server/services更改它,则会出现上述异常。 如果客户端和服务器之间的接口版本不同,则相同的例外(即使无意中添加了空行......我认为 rmi 制作了一种类的哈希来检查版本......我不知道。。。 如果它能提供帮助......

2赞 JamesKDell 10/28/2021 #14

有一个SSLPoke.bat(SSL故障排除脚本)窗口脚本,尽管将正确的证书导入到cacerts trustore中,但该脚本仍收到此错误。

C:\Java\jdk1.8.0_111\jre\lib\security>SSLPoke.bat

C:\Java\jdk1.8.0_111\jre\lib\security>"C:\jdk1.8.0_101\jre\bin\java" 
     `SSLPoke  tfs.corp.****.com  443`

java.net.SocketException: Software caused connection abort: recv failed
    `at java.net.SocketInputStream.socketRead0(Native Method)`
    `at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)`
    `at java.net.SocketInputStream.read(SocketInputStream.java:170)`
    `at java.net.SocketInputStream.read(SocketInputStream.java:141)`
    `at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)`
    `at sun.security.ssl.InputRecord.read(InputRecord.java:503)`
    `at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)`
    `at sun.security.ssl.SSLSocketImpl.performInitialHandshake
       (SSLSocketImpl.java:1375)`
    `at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:747)`
    `at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)`
    `at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)`
    `at SSLPoke.main(SSLPoke.java:28)`

然后,我检查了一些关于我工作中一些网络变化的旧笔记。我们会 在某些情况下,需要在我们的网络中添加 JVM 参数以避免此错误。-Djava.net.preferIPv4Stack=true to make connections to certain machines

C:\Java\jdk1.8.0_111\jre\lib\security>"C:\Java\jdk1.8.0_111\bin\java"  
    **-Djava.net.preferIPv4Stack=true**  SSLPoke tfs.corp.****.com 443

已成功连接

SSLPoke 的代码可以从这里下载: https://gist.github.com/4ndrej/4547029

评论

0赞 Shweta 5/11/2023
我面临类似的问题,你的回答帮助了我。谢谢