鉴于此堆栈跟踪代码段
引起:java.net.SocketException:软件导致连接中止:套接字写入错误 at java.net.SocketOutputStream.socketWrite0(Native Method)
我试着回答以下问题:
关于#1:
Sun的JVM源代码不包含这个确切的消息,但我认为文本软件导致连接中止:套接字写入错误来自SocketOutputStream
的本机实现:
private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
int len) throws IOException;
关于#2
我的猜测是,它是在客户端终止连接之前,在获得完整响应之前引起的(例如发送请求,但在获得完整响应之前,它已关闭/终止/脱机)
问题:
我需要证明这个堆栈跟踪是套接字客户端的“错误”,并且服务器没有做任何事情来避免它。 (除了捕获异常,或使用非Sun JVM SocketOutputStream,但两者都没有真正避免客户端终止的事实)
当本地网络系统中止连接时,例如,当数据重新传输失败后,WinSock关闭已建立的连接时,接收器永远不会确认数据流套接字上发送的数据,就会发生此错误。
见this MSDN article。另见Some information about 'Software caused connection abort'。
我的服务器在传递2天内抛出此异常,我通过移动断开连接功能解决了它:
outputStream.close();
inputStream.close();
Client.close();
到列表结束的线程。如果它会帮助任何人。
在下面解释的情况下,客户端将抛出这样的异常:
要求服务器验证客户端证书,但客户端提供扩展密钥用法不支持客户端身份验证的证书,因此服务器不接受客户端的证书,然后关闭连接。
ssl客户端将在下面的情况下抛出这样的异常(我测试过),:
要求服务器验证客户端证书,但客户端提供扩展密钥用法不支持客户端验证的证书。
在模拟其余的API调用时,我遇到了与wireMock相同的问题。之前我正在定义服务器,如下所示:
WireMockServer wireMockServer = null;
但它的定义应如下所示:
@Rule
public WireMockRule wireMockRule = new WireMockRule(8089);
当工作站/笔记本电脑上的公司防火墙挡住时,我经常看到这种情况,它会导致连接中断。
例如。我在同一台机器上有一个服务器进程和一个客户端进程。服务器正在侦听所有接口(0.0.0.0),客户端尝试连接到公共/ home接口(请注意不是环回接口127.0.0.1)。
如果机器的网络断开(例如wifi关闭),则形成连接。如果机器连接到公司网络(直接或vpn),则形成连接。
但是,如果机器连接到公共wifi(或家庭网络),则防火墙会启动连接。在这种情况下,将客户端连接到环回接口工作正常,而不是家庭/公共接口。
希望这可以帮助。
当创建或访问java.net.SocketException
(例如a socket)时出错,抛出TCP。这通常可以在服务器终止连接(没有正确关闭)时引起,因此在获得完整响应之前。在大多数情况下,这可能是由超时问题引起的(例如,响应花费太多时间或服务器因请求而过载),或者客户端发送了SYN,但它没有收到ACK(确认连接终止) 。对于超时问题,您可以考虑增加超时值。
套接字异常通常附带有关该问题的指定详细消息。
详细消息示例:
为了证明哪个组件出现故障,我将使用wireshark监控TCP / IP通信,并查看谁正在关闭端口,超时也可能是相关的。
您是否检查过Tomcat源代码和JVM源代码?这可能会给你更多帮助。
我认为你的一般思路很好。我希望在你无法连接的场景中有一个ConnectException
。以上看起来非常像是客户驱动的。
对于使用简单的客户端服务器程序并获得此错误的任何人来说,这是一个未闭合(或早期关闭)输入或输出流的问题。
我面临同样的问题。 通常由于客户端已关闭其连接而服务器仍在尝试在该客户端上写入,因此会发生此类错误。 因此,请确保客户端的连接处于打开状态,直到服务器完成其输出流。 还有一件事,唐不要忘记关闭输入和输出流。
希望这可以帮助。 如果仍然面临问题,请在此详细介绍您的问题。
我在使用SoapUI客户端测试我的soap服务时发生了这个错误,基本上我试图获得一个非常大的消息(> 500kb),SoapUI通过超时关闭连接。
在SoapUI上转到:
文件 - >首选项 - 套接字超时(毫秒)
...并且输入一个很大的值,例如180000(3分钟),这对你的问题不是一个完美的解决方案,因为文件实际上很大,但至少你会有一个响应。
就我而言,错误是:
java.net.SocketException: Software caused connection abort: recv failed
调试访问H2数据库的java应用程序时,它在eclipse中收到。错误的来源是我最初使用SQuirreL打开数据库以手动检查完整性。我确实使用该标志来启用到同一个DB的多个连接(即AUTO_SERVER=TRUE
),因此从java连接到DB没有问题。
一段时间后出现错误 - 这是一个很长的java进程 - 我决定关闭SQuirreL来释放资源。看起来好像SQuirreL是“拥有”数据库服务器实例的那个,并且它是通过SQuirreL连接关闭的。
重新启动Java应用程序不会再次产生错误。
配置