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

时间:2010-01-24 09:52:05

标签: java exception sockets tomcat stack-trace

鉴于此堆栈跟踪代码段

  

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

我尝试回答以下问题:

  1. 什么代码抛出此异常? (JVM?/ Tomcat?/我的代码?)
  2. 是什么导致抛出此异常?
  3. 关于#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)说明上述内容?
    4. 我需要证明这个堆栈跟踪是套接字客户端的“错误”,并且服务器没有做任何事情来避免它。 (除了捕获异常,或者使用非Sun JVM SocketOutputStream,但两者都没有真正避免客户端终止的事实)

14 个答案:

答案 0 :(得分:51)

  

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

this MSDN article。另请参阅Some information about 'Software caused connection abort'

答案 1 :(得分:8)

当工作站/笔记本电脑上的公司防火墙挡住时,我经常看到这种情况,它会破坏连接。

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

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

但是,如果机器连接到公共wifi(或家庭网络),那么防火墙就会杀死连接。在这种情况下,将客户端连接到环回接口工作正常,而不是家庭/公共接口。

希望这有帮助。

答案 2 :(得分:7)

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

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

详细消息示例:

  •   

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

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

    有关

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

  •   

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

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

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

  •   

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

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

  •   

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

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

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

  •   

    通过对等方重置连接。

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

  •   

    连接重置。

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

    请参阅:What's causing my java.net.SocketException: Connection reset?

答案 3 :(得分:4)

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

答案 4 :(得分:2)

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

我认为你的一般思想是好的。我希望在你无法连接的场景中有一个ConnectException。以上看起来非常像是客户驱动的。

答案 5 :(得分:2)

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

答案 6 :(得分:1)

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

希望这会有所帮助。
如果仍然面临问题,请详细说明您的问题。

答案 7 :(得分:0)

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

  

在SoapUI上转到:

     

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

...并且输入一个很大的值,比如180000(3分钟),这对你的问题不是一个完美的解决方案,因为文件实际上很大,但至少你会得到一个回复

答案 8 :(得分:0)

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

就我而言,错误是:

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

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

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

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

<强> 配置

  • Windows 7
  • Eclipse Kepler
  • SQuirreL 3.6
  • org.h2.Driver ver 1.4.192

答案 9 :(得分:0)

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

  

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

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

答案 10 :(得分:-1)

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

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

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

答案 11 :(得分:-1)

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

要求服务器验证客户端证书,但客户端提供的证书表明扩展密钥用法不支持客户端验证。

答案 12 :(得分:-1)

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

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

答案 13 :(得分:-3)

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

WireMockServer wireMockServer = null;

但它的定义如下所示:

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