用于套接字关闭的嵌套IOException catch

时间:2011-05-29 17:16:33

标签: java sockets exception-handling ioexception

我用socket写道:

OutputStream socketStream = socket.getOutputStream();
socketStream.write(buf);

但这可以抛出IOException,所以我这样做:

try {
  OutputStream socketStream = socket.getOutputStream();
  socketStream.write(buf);
} catch (IOException e) {
  // logging
} finally {
  socket.close();
}
  1. socket.close也迫使我抓住IOException!那么我在try ... catch中又需要finally吗?

  2. IOException抓取close时,是否表示套接字未关闭?那么再次尝试close?或者该怎么办?

  3. 由于

2 个答案:

答案 0 :(得分:3)

close()抛出IOException因为关闭某些内容通常意味着调用flush(),并且刷新可能会失败。例如,如果丢失网络连接并发出socket.close(),则无法刷新缓冲的内容,因此flush()将引发异常。由于数据可能会丢失,因此会检查异常,因此您不得不处理这种可能性。

我认为解决这个问题的最佳方法是:

try {
    OutputStream socketStream = socket.getOutputStream();
    socketStream.write(buf);
    socket.close();
} catch (IOException e) {
    // try to deal with your I/O error; do logging
} finally {
    closeSilently(socket);
}
...
// Somewhere else, usually part of an utility JAR like Apache Commons IO
public static void closeSilently(Socket s) {
    if (socket != null) {
        try {
            socket.close();
        } catch (IOException e2) {
            // do more logging if appropiate
        }
    }
}

此代码在常见情况下可正常运行。如果出现问题(甚至在close()内),它将允许您捕获异常并在无条件关闭套接字并吞下可能抛出的所有内容之前执行某些操作。

答案 1 :(得分:0)

close抛出的异常通常可以忽略(你可以记录它)。这与在C ++中的析构函数中抛出异常几乎相同 - 你可以做的并不多(通常没什么),并试图再次关闭它是荒谬的。清理抛出异常通常是糟糕的设计 - 你可以为清理实现清理代码,但这是一个递归问题,最后你只需要处理它就可以了。