是啥导致我的 java.net.SocketException:连接重置? [复制]
Posted
技术标签:
【中文标题】是啥导致我的 java.net.SocketException:连接重置? [复制]【英文标题】:What's causing my java.net.SocketException: Connection reset? [duplicate]是什么导致我的 java.net.SocketException:连接重置? [复制] 【发布时间】:2010-10-09 19:02:43 【问题描述】:我们在日志中看到频繁但间歇性的java.net.SocketException: Connection reset
错误。我们不确定Connection reset
错误实际上来自何处,以及如何进行调试。
该问题似乎与我们尝试发送的消息无关。
请注意,该消息不是 connection reset by peer
。
有关此异常的典型原因可能是什么以及我们如何进行的任何建议?
这是一个有代表性的堆栈跟踪(com.companyname.mtix.sms
是我们的组件):
我们的组件是一个 Web 应用程序,在 Tomcat 下运行,它调用发送 SMS 消息的第三方 Web 服务,它就是这样发生的。引发异常的代码行是下面代码 sn-p 的最后一行。
String aggregatorResponse = null;
HttpClient httpClient = prepareHttpClient( username, password );
PostMethod postMethod = preparePostMethod( textUrl );
try
SybaseTextMessageBuilder builder = new SybaseTextMessageBuilder();
URL notifyUrl = buildNotificationUrl( textMessage, codeSetManager );
String smsRequestDocument = builder.buildTextMessage( textMessage, notifyUrl );
LOG.debug( "Sybase MT document created as: \n" + smsRequestDocument );
postMethod.setRequestEntity( new StringRequestEntity( smsRequestDocument ) );
LOG.debug( "commiting SMS to aggregator: " + textMessage.toString() );
int httpStatus = httpClient.executeMethod( postMethod );
【问题讨论】:
正如您从完整堆栈中看到的那样,它以read
operation 开头。您的客户端已消失,但您尝试从其流中读取。请参阅我的 ServerSocket 解决方案***.com/a/31741436/413032。
【参考方案1】:
异常意味着套接字从另一端意外关闭。由于您正在调用 Web 服务,因此不应该发生这种情况 - 很可能您发送的请求会触发 Web 服务中的错误。
尝试在这些情况下记录整个请求,看看是否发现任何异常。否则,请与网络服务提供商联系并将您记录的有问题的请求发送给他们。
【讨论】:
不,它没有。那将是“对等方重置连接”。【参考方案2】:SocketException 的 javadoc 声明它是
抛出表示底层协议有错误如TCP错误
在您的情况下,连接的服务器端似乎已关闭连接。这可能是您发送的请求的问题,也可能是他们最后的问题。
为了帮助调试,您可以使用诸如Wireshark 之类的工具来查看实际的网络数据包。此外,是否有可用于测试 Web 服务的 Java 代码的替代客户端?如果此操作成功,则可能表明 Java 代码中存在错误。
当您使用 Commons HTTP 客户端时,请查看Common HTTP Client Logging Guide。这将告诉您如何在 HTTP 级别记录请求。
【讨论】:
我不相信连接重置意味着服务器关闭了连接(通过发送 FYN 标志)。我相信这意味着它不再响应 ACK 标志,或者它没有响应每个 TCP/IP)。如果发送了 FYN 标志,或者更确切地说是服务器关闭了连接,您只会从 read() 中获得 -1 和 EOFException。当我回到家时,我计划以任何方式确认这一点。 回应僵尸评论,有没有人发现连接重置是否意味着服务器已经关闭了连接? 根据我过去遇到类似问题的经验,原因是服务器端的网络连接不好,导致连接超时。 Socket 超时的问题在于它的默认行为是不超时(无限超时)。 (继续) (继续)即使是 HTTPClient 也没有在创建的套接字上设置默认超时。另一方面,服务器端的所有套接字必须在几分钟后超时,否则连接将被卡住(在服务器上非常糟糕)。因此,如果服务器端连接超时,客户端将重置连接(服务器关闭连接),如果客户端首先超时,则异常将是 ConnectionTimeoutException。由于这是一个暂时性问题,解决方案是捕获并记录所有这些异常,然后重试。 @FilipePalrin 你说得很对,HttpClient 没有在套接字连接上设置有限超时。【参考方案3】:当客户端在通过套接字返回响应之前关闭套接字连接时,服务器端会发生此错误。在 Web 应用场景中,并非所有这些都是危险的,因为它们可以手动创建。例如,在检索到响应之前退出浏览器。
【讨论】:
虽然如此,但这个问题是关于一个客户端组件,您希望服务器在该组件中完成交换。【参考方案4】:此错误发生在您这边,而不是另一边。如果对方重置了连接,那么异常信息应该是:
java.net.SocketException reset by peer
原因是HttpClient
内部的连接已过时。检查 SSL 的陈旧连接不能修复此错误。解决方案:转储您的客户端并重新创建。
【讨论】:
【参考方案5】:我一直收到这个错误,认为这是正常的。
当另一方已经挂断时一方尝试阅读时会发生这种情况。因此根据协议,这可能会或可能不会指定问题。 如果我的客户端代码明确向服务器表明它将挂断,那么客户端和服务器都可以同时挂断,并且不会出现此消息。
我实现代码的方式是让客户直接挂断而不说再见。 然后服务器可以捕获错误并忽略它。在 HTTP 的上下文中,我相信协议的一个级别允许每个连接一个以上的请求,而另一个不允许。
因此,您可以看到一方可能会继续挂断另一方。我怀疑您收到的错误是否存在任何盗版问题,您可以简单地捕获它以防止它填满您的日志文件。
【讨论】:
在这种情况下,协议显然是 HTTP,因此不应发生,除非连接的另一端退出的极少数情况。 没有。发送方可以在接收方仍有许多 KB 未读取的数据时关闭。在这种情况下,接收器将读取所有数据,然后获得流结束,而不是重置。【参考方案6】:我也遇到了这个错误:Connection reset by peer
。 Spring 的 REST 模板在运行 postForObject()
方法时引发了异常。对我来说,问题是 HTTP URL 请求太长。所以首先检查生成的 URL 是否是它应该是的,如果你的服务器真的应该能够处理该长度的请求,只需转到服务器的配置并提高 URL 请求的默认允许长度。
这解决了我的问题,但请注意:该应用程序可能无法在某些 Internet 浏览器上运行,尤其是旧浏览器,因为它们具有固定的最大 URL 请求长度。
希望对你有帮助...
【讨论】:
Connection reset
与 Connection reset by peer
不同。【参考方案7】:
如果您在尝试访问部署在 Glassfish3 服务器上的 Web 服务时遇到这种情况,您可能需要调整您的 http-thread-pool 设置。这修复了当许多并发线程调用 Web 服务时我们遇到的 SocketException。
-
转到管理控制台
导航到“配置”->“服务器配置”->“线程池”->“http-thread-pool”。
将“最大线程池大小”设置从 5 更改为 32
将“最小线程池大小”设置从 2 更改为 16
重新启动 Glassfish。
【讨论】:
这对 Glassfish 4 也有帮助【参考方案8】:在我的例子中,这是因为我的 Tomcat 设置的 maxHttpHeaderSize
不足以用于特别复杂的 SOLR 查询。
希望这对那里的人有所帮助!
【讨论】:
【参考方案9】:我也偶然发现了这个错误。就我而言,问题是我使用的是 JRE6,支持 TLS1.0。服务器只支持TLS1.2,所以抛出了这个错误。
【讨论】:
很难相信。你应该有一个SSLHandshakeException
。
@EJP:我的答案是很久以前写的,所以我不能再检查这个问题了。我只记得绊倒了这个错误+更新到 TLS 1.2 解决了这个问题。经过短暂的谷歌搜索后,我看到其他人也得到了java.net.SocketException
,当使用 TLS1.0 与至少支持 TLS1.2 的服务器组合时。例如assuresign.tenderapp.com/kb/how-to/….
是的,Java 7 也可能发生这种情况。默认的 TLS 实现是 TLSv1,以ClientHello
发送;如果服务器不支持它,你会得到一个Connection reset
,而不是SSLHandshakeException
。【参考方案10】:
我知道这个帖子有点旧,但想加我的 2 美分。 在我们发布其中一个版本之后,我们立即遇到了相同的“连接重置”错误。
根本原因是,我们的apache
服务器被关闭以进行部署。我们所有的第三方流量都通过apache
,并且由于连接中断,我们遇到了连接重置错误。
【讨论】:
【参考方案11】:当我尝试读取的文本文件包含与我们防火墙上的防病毒签名匹配的字符串时,我收到此错误。
【讨论】:
【参考方案12】:这是一个旧线程,但我昨天遇到了java.net.SocketException: Connection reset
。
服务器端应用程序的限制设置已更改为一次只允许 1 个连接!因此,有时电话会通过,有时不会。我通过更改限制设置解决了这个问题。
【讨论】:
【参考方案13】:FWIW,当我不小心向期望 POST 请求的端点发出 GET 请求时,我收到了这个错误。大概这就是处理问题的特定服务器方式。
【讨论】:
【参考方案14】:我收到此错误是因为我尝试连接的端口已关闭。
【讨论】:
这会导致连接超时或连接被拒绝。以上是关于是啥导致我的 java.net.SocketException:连接重置? [复制]的主要内容,如果未能解决你的问题,请参考以下文章