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


157

给定此堆栈跟踪代码段

引起原因: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除外,尽管两者都不能真正避免客户端已终止的事实)


取消使用Firefox的下载时遇到此问题
koppor 13/10/25

嘿,同时发送/写(叶兰我也收到这个例外outs.write(audioBytes);byte[]OutputStream。当音频播放并且播放时,如果用户单击任何其他菜单(发送服务器请求),则在控制台上会出现相同的错误。那么忽略此异常是否安全?
Amogh

1
@Amogh-看来是的。基本上从答案的描述来看,这是Windows特定的错误,但是我认为在Linux上,您会使用不同的措辞得到相同的异常...(我的外行人认为,基本上,这是由于您发送时引起的通过套接字连接到某个远程位置X和X在中间断开了连接,但我敢肯定这不是描述它的最准确方法)
Eran Medan 2015年

1
对我来说,这是在重新启动数据库服务器并且应用程序仍尝试使用先前打开的连接进行查询时发生的。不知道为什么在使用基于DBCP的池时没有刷新这些内容。但是重新启动应用程序可以解决问题。
Kshitiz Sharma '02

Answers:


55

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

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



3
@MatGessel该文章只是重复了混乱,并增加了一些混乱之处。WSAECONNABORTED是Winsock错误代码,因此不可能有Berkeley对其进行解释。描述的有关HTTP服务器的情况将产生ECONNRESET,而不是WSAECONNABORTED。
罗恩侯爵,

@EJP,在向OutputStream发送/写入(outs.write(audioBytes);)byte []时,我也收到此异常。当音频播放并且播放时,如果用户单击任何其他菜单(发送服务器请求),则在控制台上会出现相同的错误。那么忽略此异常是否安全?
2015年

1
@rustyx此处引用的所有三个来源都指出,它是由ACK故障产生的。如果您有自己的主张来源,请引用它。
罗恩侯爵

2
这不是真正的答案,因为它不会给您提供进一步解决该问题的信息。答案基本上是“网络上发生了不好的事情”。了解进一步的日志和其他活动记录可以使我查明潜在的问题确实很有帮助。
Derek Bennett

11

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

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

详细消息示例:

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

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

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

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

    当连接到遥控器时出现问题。例如,由于病毒检查程序拒绝了远程邮件请求

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

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

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

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

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

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

  • 对等方重置连接。

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

  • 连接重置。

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

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


这6点中只有1点实际上是错误地回答了这个问题。其他几个也不正确。应用程序无法 “检查服务器端的保持活动连接是否已超时”。该HttpClient之中null不可能引起SocketException。没有向流中写入正确的长度也不会。
罗恩侯爵

9

我最经常看到的是工作站/笔记本电脑上的公司防火墙妨碍了它的连接。

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

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

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

希望这可以帮助。


3
防火墙阻止连接。问题是关于重置现有连接。
罗恩侯爵,

4

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


没有人关闭港口。操作系统正在中止连接。
2014年

@EJP我已经看到,当过载和内存不足时会发生这种情况。我不确定是操作系统关闭了连接,但是JVM变得疯狂了。
Zee 2015年

1
@Zee在关闭端口(在Wireshark中可以看成FIN)与中止连接(不是)之间有区别。
罗恩侯爵,2015年

2

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

我认为您的一般想法很好。我希望ConnectException在无法连接的情况下出现一个。上面看起来很像它是由客户端驱动的。


3
是的,我已经检查过了。Tomcat的来源没有包含该句子的任何排列,谢谢。
伊兰·棉兰

1
不,他还没有检查过Tomcat源 JVM源。
斯蒂芬·C

或者,如果他已经检查了JVM源,那么他还没有检查所有源。
斯蒂芬·C

1
@Ehrann-消息字符串最有可能在本机源中。但是,您还应该检查事件日志。IMO,后者可能会提供更多信息。
斯蒂芬·C

6
该消息字符串实际上来自操作系统。
,洛恩侯爵

2

对于使用简单Client Server程序并收到此错误的任何人,这都是未封闭(或封闭至早期)的输入或输出流的问题。


2
不,不是。这将导致插座泄漏,最终导致FD耗尽。
罗恩侯爵,2015年

0

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

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


3
@BhavinChhatrola不,答案不正确。所描述的情况将产生“由对等方重置连接”,而不是问题中的错误。
罗恩侯爵

0

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

在SoapUI上,转到:

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

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


0

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

就我而言,错误是:

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

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

一段时间后(这是一个漫长的Java进程),我决定关闭SQuirreL以释放资源,从而出现错误。似乎SQuirreL是数据库服务器实例的“所有者”,并且它已通过SQuirreL连接关闭。

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

配置

  • Windows 7的
  • 日蚀开普勒
  • SQuirreL 3.6
  • org.h2.Driver版本1.4.192

0

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

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

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


-1

我的服务器在过去的两天内抛出了此异常,我通过使用以下方法移动断开连接的函数来解决了该异常:

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

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


-1

在下面说明的情况下,客户端将引发此类异常:

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


这个答案是不正确的。在您描述的情况下,将抛出SSLException。
总统詹姆斯·波尔克(James K. Polk)'18年

实际上,它像当前问题一样抛出SocketException,我已经测试过
xiaoming

-1

ssl客户端将在以下情况下抛出此类异常(我已经测试过),:

服务器被要求对客户端证书进行身份验证,但是客户端提供了扩展密钥用法不支持客户端身份验证的证书。


-3

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

WireMockServer wireMockServer = null;

但它的定义应如下所示:

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

那会导致一个NullPointerException问题,而不是这个问题。
罗恩侯爵
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.