当 socket.close() 抛出 Java 时我能做啥?
Posted
技术标签:
【中文标题】当 socket.close() 抛出 Java 时我能做啥?【英文标题】:Anything I can do when socket.close() throws in Java?当 socket.close() 抛出 Java 时我能做什么? 【发布时间】:2011-10-24 02:33:18 【问题描述】:一周前开始学习 java,并决定学习处理异常的正确方法。 Java 真的让我发疯了,因为指定方法可以抛出异常作为其签名的一部分。
我目前正在尝试为客户端-服务器应用程序实现多线程服务器。我对socket.close()
可以抛出 IOException 的事实感到非常惊讶。问题是,如果发生了我该怎么办?
...
final Socket socket = .... // at this point I know that I have a good socket
try
..... // communicating with someone on that side....
catch(IOException e)
// communication failed
// this fact is useful, I can log it
// and will just hang up
finally
try
socket.close(); // bye-bye
catch(IOException e)
// anything but logging I can do here?
...
这段代码是在一个单独的线程中执行的,所以我只需要必须捕获所有的异常。问题主要是心理上的 - 我知道,我可以将 catch
块留空,但我试图避免这个技巧。
有什么想法吗?
【问题讨论】:
那里没有很多事情可以做。最近的 Java 7 版本有一个try-with-resources
块,它会自动关闭您在 try 块中指定的任何资源,这有望永远解决这个问题。这个博客上有一个很好的例子:baptiste-wicht.com/2010/08/java-7-try-with-resources-statement
对语义感到好奇。 FileInputStream.close()
throws - 在这种情况下会是什么样子?
快讯:Java 7 is no longer upcoming ;-)
@Joachim,你是对的。出于某种原因,我以为是八月底而不是七月
Who cares?
【参考方案1】:
关闭资源失败时您不做任何重大的事情是很常见的。记录日志可能是个好主意,这样您就有机会了解它是否更频繁地发生。
如果关闭资源也是“提交”或以其他方式保持更改,则情况不同:那么您需要像对待任何其他部分的异常一样对待它:处理它。
请注意,Java 7 专门引入了automatic resource management 来简化这些类型的结构。如果您现在学习 Java,那么我建议您使用最新最好的。
【讨论】:
【参考方案2】:我想这取决于您是从套接字读取数据还是向其写入数据。如果您读取数据并检索到您想要的所有信息,那么您可以放心地忽略该异常。但是,如果您编写数据,您可能不得不假设它没有正确传输。
【讨论】:
【参考方案3】:Apache Commons IO(一个我几乎无法编写 Java 的库)有一个方法 IOUtils.closeQuietly()
用于此目的。
所以你可以这样做:
final Socket socket = .... // at this point I know that I have a good socket
try
..... // communicating with someone on that side....
catch(IOException e)
// communication failed
// this fact is useful, I can log it
// and will just hang up
finally
IOUtils.closeQuietly(socket);
并为自己节省 5 行代码。
作为奖励,closeQuietly()
在套接字为空或已关闭时会做正确的事情。还有其他任何东西 Closeable
的重载。
【讨论】:
socket 为 null 或已经关闭,如果你有一个 null 套接字,那么你的代码、逻辑中确实存在错误。 (final socket
= 不应导致 null 而是异常)
@bestsss:确实,在给定的代码示例中永远不会发生这种情况。我想说的是IOUtils.closeQuietly()
是一个方便的实用函数,也可以在其他情况下使用。【参考方案4】:
正如 cmets 中所说,您无能为力。我建议你无论如何都要记录一个错误,这样如果它确实发生了,你至少有一个地方可以开始寻找。
【讨论】:
【参考方案5】:这引起了很多人的注意,强制捕获这样的嵌套异常。
您应该记录它,最好使用像 Log4J 这样强大的工具,否则我会说忽略它是安全的,除了“故意忽略”的评论。
【讨论】:
【参考方案6】:除了捕获并记录它之外,您无法处理 close 引发的异常。重要的是,如果你让它被抛出,并且如果在到达 close 方法之前抛出了另一个异常,那么 close 方法可能会抛出一个异常来掩盖第一个异常,它不会出现任何地方,你都不会知道真正的问题是什么。所以你肯定不想要那个。
【讨论】:
以上是关于当 socket.close() 抛出 Java 时我能做啥?的主要内容,如果未能解决你的问题,请参考以下文章
springboot集成RabbitMQ,Eclipse开发集成RabbitMq,IDEA集成RabbitMQ报错 socket close