java.net.SocketException:软件导致连接中止:recv失败

gra*_*r31 75 java sockets

我无法找到适当的答案,以确定以下错误的含义:

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

笔记:

  • 这个错误不常见且不可预测; 虽然获取此错误意味着将来所有URI请求也将失败.
  • 有效的唯一解决方案(也是偶尔)是重启Tomcat和/或实际机器(在本例中为Windows).
  • URI绝对可用(通过要求浏览器进行提取来确认).

相关代码:

BufferedReader reader;
try { 
 URL url = new URL(URI);
 reader = new BufferedReader(new InputStreamReader(url.openStream())));
} catch( MalformedURLException e ) { 
 throw new IOException("Expecting a well-formed URL: " + e); 
}//end try: Have a stream

String buffer;
StringBuilder result = new StringBuilder();
while( null != (buffer = reader.readLine()) ) { 
 result.append(buffer); 
}//end while: Got the contents.
reader.close();
Run Code Online (Sandbox Code Playgroud)

Ada*_*amC 25

这通常意味着存在网络错误,例如TCP超时.我首先在连接上放置一个嗅探器(wireshark),看看你是否能看到任何问题.如果存在TCP错误,您应该能够看到它.此外,如果适用,您可以检查路由器日志.如果无处不在任何地方,那么这就是这类错误的另一个来源.


小智 23

如果您的TLS客户端无法由配置为要求客户端身份验证的服务器进行身份验证,也会发生这种情况.

  • 身份验证失败时,某些API确实发生在我身上。所以,谢谢@desbocages。 (2认同)

rus*_*tyx 10

当连接突然关闭时(当发送缓冲区中仍有数据时重置TCP连接时)会发生此错误.这种情况非常类似于更常见的"由同行重置连接".它可能在通过Internet连接时偶尔发生,但如果时间正确则会系统地发生(例如,在localhost上保持活动连接).

HTTP客户端应该只是重新打开连接并重试请求.重要的是要理解当连接处于这种状态时,除了关闭它之外没有其他方法可以解决.任何发送或接收的尝试都会产生相同的错误.

不要使用URL.open(),使用Apache-Commons HttpClient,它具有重试机制,连接池,保持活动和许多其他功能.

样品用法:

HttpClient httpClient = HttpClients.custom()
            .setConnectionTimeToLive(20, TimeUnit.SECONDS)
            .setMaxConnTotal(400).setMaxConnPerRoute(400)
            .setDefaultRequestConfig(RequestConfig.custom()
                    .setSocketTimeout(30000).setConnectTimeout(5000).build())
            .setRetryHandler(new DefaultHttpRequestRetryHandler(5, true))
            .build();
// the httpClient should be re-used because it is pooled and thread-safe.

HttpGet request = new HttpGet(uri);
HttpResponse response = httpClient.execute(request);
reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
// handle response ...
Run Code Online (Sandbox Code Playgroud)

  • 是的,它确实.我建议你在给-1之前做一些研究.我们确实做到了.'连接重置'是由TCP RST数据包引起的,但是当在发送缓冲区中仍有数据时接收到TCP RST时,应用程序的后续`recv()`将导致`WSAECONNABORTED`错误,该错误转换为有问题的例外.我想知道你的*解释是针对这个例外的.你说的"修复网络" - 我可以用几行代码在localhost上重现这个. (4认同)