简体   繁体   English

当 socket.close() 抛出 Java 时,我能做什么?

[英]Anything I can do when socket.close() throws in Java?

Started learning java a week ago and also decided learning the right way to work with exceptions.一周前开始学习 java 并决定学习处理异常的正确方法。 Java really drives me mad with the idea of specifying exceptions the method can throw as part of its signature. Java 真的让我很生气,因为指定方法可以抛出异常作为其签名的一部分。

I'm currently trying to implement multi-threaded server for client-server application.我目前正在尝试为客户端-服务器应用程序实现多线程服务器。 I was very surprised with the fact socket.close() can throw IOException.我对socket.close()可以抛出 IOException 的事实感到非常惊讶。 The question is, what do I do if it happens?问题是,如果发生这种情况我该怎么办?

...
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?
  }
}
...

This piece of code is executed within a separate thread, so I just have to catch all the exceptions.这段代码在一个单独的线程中执行,所以我只需要捕获所有的异常。 The problem is mostly psychological - I know, I can just leave catch block empty, but I'm trying to avoid this trick.问题主要是心理上的——我知道,我可以把catch块留空,但我试图避免这个把戏。

Any thoughts?有什么想法吗?

It's quite common that you don't do anything major when closing a resource fails.当关闭资源失败时,您不做任何重大的事情是很常见的。 Logging is probably a good idea, so that you have a chance to find out if it happens more often.记录可能是一个好主意,这样您就有机会了解它是否更频繁地发生。

This is different if closing the resource is also the "commit" or in some other way persists the change: then you'd need to treat it just like you would treat an exception in any other part: handle it.如果关闭资源也是“提交”或以其他方式保持更改,这是不同的:那么您需要像对待任何其他部分的异常一样对待它:处理它。

Note that Java 7 has introduced automatic resource management specifically to simplify these kinds of constructs.请注意,Java 7 专门引入了自动资源管理来简化这些类型的结构。 And if you learn Java now, then I'd suggest going with the latest-and-greatest.如果您现在学习 Java,那么我建议您使用最新最好的。

I guess it depends if you read data from the socket or wrote data to it.我想这取决于您是从套接字读取数据还是向其写入数据。 If you read data and retrieved all the info you wanted then you can safely ignore the exception.如果您读取数据并检索到您想要的所有信息,那么您可以放心地忽略该异常。 But if you wrote data you probably have to assume that it did not get transmitted correctly.但是,如果您编写数据,您可能不得不假设它没有正确传输。

Apache Commons IO (a library that I can't hardly write Java without) has a method IOUtils.closeQuietly() for just this purpose. Apache Commons IO (一个我几乎无法编写 Java 的库)有一个方法IOUtils.closeQuietly()仅用于此目的

So you can do:所以你可以这样做:

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);
}

and save yourself 5 lines of code.并为自己节省 5 行代码。

As a bonus, closeQuietly() does the right thing if the socket is null or already closed.作为奖励,如果套接字是 null 或已经关闭, closeQuietly()会做正确的事情。 And there are overloads for anything else Closeable as well.其他任何Closeable的东西也有重载。

As said in the comments, there's not much you can do there.正如评论中所说,您在那里无能为力。 I suggest you log an error anyway, this way if it ever does happen, you at least have a place to start looking.我建议你无论如何都要记录一个错误,这样如果它真的发生了,你至少有一个地方可以开始寻找。

That catches a lot of folks out, the compulsion to catch nested exceptions like that.这引起了很多人的注意,强制捕获这样的嵌套异常。

You should log it, ideally using something robust like Log4J, but otherwise I would say it's safe to ignore it, other than a comment saying "deliberately ignoring".你应该记录它,理想情况下使用像 Log4J 这样强大的东西,但否则我会说忽略它是安全的,除了评论说“故意忽略”。

There is nothing you can do with the exception thrown by close except catch it and log it.除了捕获并记录它之外,您无法处理 close 引发的异常。 The important thing is that if you were to let it be thrown, and if there was another exception that was thrown before the close method was reached, the close method could throw an exception that would mask the first exception, it wouldn't show up anywhere and you wouldn't know what the real problem was.重要的是,如果你让它被抛出,并且如果在到达 close 方法之前抛出了另一个异常,那么 close 方法可能会抛出一个异常来掩盖第一个异常,它不会出现任何地方,你都不会知道真正的问题是什么。 So you definitely don't want that.所以你绝对不想要那个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM