繁体   English   中英

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

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

鉴于此堆栈跟踪片段

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

我试图回答以下问题:

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

关于#1:

Sun 的 JVM 源不包含此确切消息,但我认为文本软件导致连接中止:套接字写入错误来自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,尽管两者都没有真正避免客户端已终止的事实)

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

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

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

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

详细消息示例:

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

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

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

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

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

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

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

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

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

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

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

  • 对等方重置连接。

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

  • 连接重置。

    连接要么被客户端终止,要么被连接的服务器端关闭,因为请求带有请求。

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

当工作站/笔记本电脑上的企业防火墙妨碍连接时,我最常看到这种情况。

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

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

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

希望这可以帮助。

为了证明哪个组件出现故障,我将使用wireshark监视TCP/IP 通信并查看谁实际关闭了端口,超时也可能相关。

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

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

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

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

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

有一个 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我们网络中的-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

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

在 SoapUI 上转到:

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

...并输入一个较大的值,例如 180000(3 分钟),这不是解决您问题的完美方法,因为该文件实际上太大了,但至少您会有响应。

在另一个客户端关闭连接

就我而言,错误是:

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

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

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

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

配置

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

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

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

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

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

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

给定此堆栈跟踪代码段

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

我试图回答以下问题:

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

关于#1:

Sun的JVM源不包含此确切消息,但我认为文本软件导致连接中止:套接字写入错误来自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.net.SocketException:软件导致连接中止:套接字写入错误

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

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

WireMockServer wireMockServer = null;

但它应该定义如下:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM