【问题标题】:Closing a socket [closed]关闭套接字[关闭]
【发布时间】:2013-12-23 22:38:57
【问题描述】:

我有一个套接字和四个由它创建的流:

  • InputStream
  • OutputStream
  • ObjectInputStream
  • ObjectOutputStream

我需要做什么才能关闭所有流以及套接字?我认为关闭套接字就足够了,但我得到了EOFExceptions...

代码越少越好。

关于问题的更多信息:

我打开一个连接并发送 UTF String trought 对象流。它的内容在服务器上启动不同的协议。执行协议时,服务器等待新的 UTF 字符串。

在某一时刻,客户端执行:

objectOutputStream.writeUTF("terminate");
objectOutputStream.flush(); //Is this even necessary?
socket.close();

在服务器端,会发生这样的事情:

String command = objectInputStream.readUTF();
if (command.equals("terminate")
{
    socket.close();
}

//socket is not accessed after this point, until a new conenction is established
//(when socket and everything is reinitialized)

【问题讨论】:

  • 除了异常之外,你在关闭套接字后有什么期望?
  • 当您关闭套接字时,您也在关闭这些套接字的流/来自这些套接字的流。如果您尝试对关闭的流(关闭的套接字)进行操作,您应该得到一个异常和/或 EOF。
  • 如果你用BufferedOutputStream 包裹它,你可以跳过.flush()。由于您使用Decorator 模式作为流,您可以关闭最外层。

标签: java sockets inputstream outputstream


【解决方案1】:

使用 try-with-resources 块,这一切都会为您处理:

try (InputStream is = new InputStream(socket);
    OutputStream os = new OutputStream(socket);
    ObjectInputStream ois = new ObjectInputStream(is)
    ObjectOutputStream oos = new ObjectInputStream(os)) {
   // Do stuff here
}

当您退出 try 块时,您的所有流(以及实现 AutoCloseable 的任何其他内容都将自动为您关闭。

要在关闭保持流时关闭底层流,它也会关闭较低的流(即关闭ois 也会关闭is),但将它们全部保留在 try-with-资源块。

【讨论】:

  • 那么我应该关闭对象流和套接字本身吗?还是只是对象流?
  • 如果有疑问关闭它们(套接字也是AutoCloseable)。真正的问题是为什么你在关闭套接字后仍然试图读取/写入流......因为那是行不通的:)
【解决方案2】:
  1. 您只需要关闭最外层的输出流或您已经包裹在套接字输出流周围的 Writer。这样可以确保它被刷新。

  2. 关闭任何流或套接字会关闭其他流。

  3. EOFException 是正常的。这意味着你已经到达了流的末尾。

【讨论】:

  • 所以每次关闭socket都会抛出EOFException?不是在尝试从关闭的套接字/流中读取时?
  • 没有。当您为返回 null 的 readLine() 以外的任何 X 调用 readXXX() 时,将引发 EOFException; read() 返回 -1。当 peer 关闭连接时,而不是当 you 关闭 socket 时。
猜你喜欢
  • 1970-01-01
  • 2011-05-08
  • 1970-01-01
  • 2013-07-17
  • 2011-01-26
  • 2016-07-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多