【问题标题】:Official reasons for "Software caused connection abort: socket write error"“软件导致连接中止:套接字写入错误”的官方原因
【发布时间】:2011-01-08 18:08:24
【问题描述】:

鉴于此堆栈跟踪 sn-p

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

我尝试回答以下问题:

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

关于#1:

Sun 的 JVM 源代码不包含此确切消息,但我认为文本 Software cause 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,虽然两者都不能真正避免客户端已经终止的事实)

【问题讨论】:

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

标签: java exception sockets tomcat stack-trace


【解决方案1】:

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

this MSDN article。另见Some information about 'Software caused connection abort'

【讨论】:

  • @MatGessel 那篇文章只是重复了混淆,并添加了一些自己的内容。 WSAECONNABORTED 是一个 Winsock 错误代码,因此不可能有伯克利的解释。描述的关于 HTTP 服务器的情况将产生 ECONNRESET,而不是 WSAECONNABORTED。
  • @EJP,我在向 OutputStream 发送/写入 (outs.write(audioBytes);) byte[] 时也遇到了这个异常。当音频播放和播放时,如果用户单击任何其他菜单(发送服务器请求),我在控制台上遇到了同样的错误。那么忽略这个异常是否安全?
  • @rustyx 这里引用的所有三个来源都表明它是由 ACK 失败产生的。如果您有自己声明的来源,请注明。
  • 这不是一个真正的答案,因为它没有为您提供进一步解决问题的信息。这里的答案基本上是“网络上发生了一些不好的事情”。了解哪些进一步的日志和其他活动记录可以让我查明根本问题,这将非常有帮助。
【解决方案2】:

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

Socket Exception 通常带有关于该问题的指定详细消息。

详细信息示例:

  • 软件导致连接中止:recv failed.

    该错误表示尝试发送消息并且连接已被您的服务器中止。如果在连接数据库时发生这种情况,这可能与使用 not compatible Connector/J JDBC driver 有关。

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

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

    当连接到遥控器出现问题时,可能会发生这种情况。例如due to virus-checker rejecting the remote mail requests

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

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

    可能的解决方案:确保将正确长度的字节写入流。因此,请仔细检查您发送的内容。看到这个thread

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

    应用程序没有检查保持连接是否在服务器端超时。

    可能的解决方案:确保 HttpClient 在读取连接之前不为空。E13222_01

  • 对等方重置连接。

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

  • 连接重置。

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

    见:What's causing my java.net.SocketException: Connection reset?

【讨论】:

  • 这 6 点中只有 1 点实际上回答了问题,不正确。其他几个也是不正确的。应用程序无法 '检查保持连接是否在服务器端超时。' HttpClientnull 不可能导致 SocketException。没有将正确的长度写入流也不会。
【解决方案3】:

当工作站/笔记本电脑上的企业防火墙挡路时,我经常看到这种情况,它会终止连接。

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

如果机器的网络断开连接(例如 wifi 关闭),则建立连接。如果机器连接到公司网络(直接或 vpn),那么连接就形成了。

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

希望这会有所帮助。

【讨论】:

  • 防火墙阻止连接。问题是关于重置现有连接。
【解决方案4】:

为了证明哪个组件发生故障,我将使用wireshark 监控 TCP/IP 通信,并查看谁在实际关闭端口,也可能与超时有关。

【讨论】:

  • 没有人关闭端口。操作系统正在中止连接。
  • @EJP 我已经看到当超载和内存不足时会发生这种情况。我不确定是操作系统关闭了连接,但 JVM 变得狂野。
  • @Zee 关闭端口(在 Wireshark 中作为 FIN 可见)和中止连接(不是这样)是有区别的。
【解决方案5】:

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

【讨论】:

  • 不,不是。这将构成套接字泄漏,最终导致 FD 耗尽。
【解决方案6】:

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

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

【讨论】:

  • 是的,我已经检查过了。 Tomcat 的源代码中不包含任何对句子的排列,谢谢。
  • 不,他没有检查 Tomcat 源 AND JVM 源。
  • 或者如果他检查了JVM源,他还没有检查所有的。
  • @Ehrann - 消息字符串最有可能在本机源中。但是您还应该检查事件日志。 IMO,后者可能会提供更多信息。
  • 这个消息字符串实际上来自操作系统。
【解决方案7】:

我也遇到了同样的问题。
通常这种错误是由于客户端已关闭其连接而服务器仍在尝试在该客户端上写入。
因此,请确保您的客户端打开连接,直到服务器完成其输出流。
还有一件事,别忘了关闭输入和输出流。

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

【讨论】:

  • @BhavinChhatrola 不,答案不正确。所描述的情况会产生“对等方重置连接”,而不是问题中的错误。
【解决方案8】:

有一个 SSLPoke.bat(SSL 故障排除脚本)窗口脚本,尽管将正确的证书导入 cacerts 信任库,但仍出现此错误。

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

【讨论】:

    【解决方案9】:

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

    在 SoapUI 上转到:

    File-->Preferences--Socket Timeout(ms)

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

    【讨论】:

      【解决方案10】:

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

      就我而言,错误是:

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

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

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

      重新启动 Java 应用程序并没有再次产生错误。

      配置

      • Windows 7
      • Eclipse 开普勒
      • 松鼠 3.6
      • org.h2.Driver 版本 1.4.192

      【讨论】:

        【解决方案11】:

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

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

        【讨论】:

        • 这个答案不正确。在您描述的情况下,将抛出 SSLException。
        • 实际上它会抛出 SocketException 就像我测试过的当前问题一样
        【解决方案12】:

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

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

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

        【讨论】:

          【解决方案13】:

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

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

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

          【讨论】:

            【解决方案14】:

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

            WireMockServer wireMockServer = null;
            

            但它应该如下定义:

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

            【讨论】:

            • 那会导致NullPointerException,而不是这个问题。
            猜你喜欢
            • 2011-02-21
            • 2019-07-27
            • 2016-03-04
            相关资源
            最近更新 更多