有没有办法仅忽略“connection reset by peer” IOExceptions?

3

我对由于网络问题导致套接字读取调用抛出大量 IOException 非常烦恼。通常情况下,这仅意味着有人杀死了子进程或网络严重崩溃(VPN 连接断开等)。

我的服务器无法做任何事情,但我真的不想在日志文件中看到所有这些错误。在 Java 中是否有忽略这些异常的方法?

我知道在 Windows MSDN 级别上,它是 WSAENETRESET 错误,那么为什么所有错误都被处理为通用的 IOException,而不是 ConnectionResetException。

由同行重置连接是非常通用和标准的。

我无法确定异常消息是否会出现在不同的 Windows 操作系统语言环境中。


你不能在你的日志库中过滤它吗?你使用log4j吗? - plus-
是的,我在考虑添加一个可以忽略的异常消息列表。但我需要将其配置为可配置的,以便客户可以输入本地化字符串。 - Neil Wightman
3个回答

3
你可以使用 getMessage() 方法查看异常信息是否如下所示:

Connection reset by peer

这不应该返回本地化版本的错误消息。似乎是通过 getLocalizedMessage() 完成的。

我也不知道那个。也许这意味着错误总是“连接被对等方重置”。现在我只需要确保nio也是相同的错误。看起来nio可能是“现有连接被远程主机强制关闭”而不是。 :) - Neil Wightman
2
你应该考虑删除这个回答,因为它是错误的。请看我的回答以获得证明。不幸的是,我自己还没有解决方案。 - Evgeniy Berezovsky

2
这并不是解决方案,只是为了证明 npinti 的答案听起来合理,但在我尝试确认时被证明是不准确的,因此误导开发人员构建在非英语系统上无法按预期工作的解决方案:

与人们可能期望的相反,IOException.getMessage() 返回的本地化字符串与 IOException.getLocalizedMessage() 相同

运行此代码时:

try {
    client.read(byteBuf);
} catch (IOException ioe) {
    System.out.println("IOException.getMessage(): \"" + ioe.getMessage() + "\"");
    System.out.println("IOException.getLocalizedMessage(): \"" + ioe.getLocalizedMessage() + "\"");
    throw ioe;
}

在日本的Windows系统上,输出结果如下:
IOException.getMessage(): "既存の接続はリモート ホストに強制的に切断されました。"
IOException.getLocalizedMessage(): "既存の接続はリモート ホストに強制的に切断されました。"
Exception in thread "main" java.io.IOException: 既存の接続はリモート ホストに強制的に切断されました。
        at java.base/sun.nio.ch.SocketDispatcher.read0(Native Method)
        at java.base/sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:43)
        at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:276)
        at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:245)
        at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:223)
        at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:353)
        at Test.main(Test.java:21)

在英文Linux上,它应该是这样的:
IOException.getMessage(): "Connection reset by peer"
IOException.getLocalizedMessage(): "Connection reset by peer"
Exception in thread "main" java.io.IOException: Connection reset by peer
        at java.base/sun.nio.ch.FileDispatcherImpl.read0(Native Method)
        at java.base/sun.nio.ch.SocketDispatcher.read(SocketDispatcher.java:39)
        at java.base/sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:276)
        at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:245)
        at java.base/sun.nio.ch.IOUtil.read(IOUtil.java:223)
        at java.base/sun.nio.ch.SocketChannelImpl.read(SocketChannelImpl.java:353)
        at Test.main(Test.java:21)

Windows Java版本:

openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment Temurin-11.0.12+7 (build 11.0.12+7)
OpenJDK 64-Bit Server VM Temurin-11.0.12+7 (build 11.0.12+7, mixed mode)

Linux Java版本:

openjdk version "11.0.12" 2021-07-20
OpenJDK Runtime Environment (build 11.0.12+7-Ubuntu-0ubuntu3)
OpenJDK 64-Bit Server VM (build 11.0.12+7-Ubuntu-0ubuntu3, mixed mode, sharing)

0

一种方法是,由于连接被重置,您可以尝试在catch块本身中连接到远程。因此,如果仍然无法通过,则表示远程系统仍然处于停机状态,您可以相应地重复此操作/处理此操作。

如果这只是短暂的,并且您现在能够连接,那么您可以以某种方式重新建立连接。

另一种方法是按@npinti所述,在catch块中检查异常内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接