【问题标题】:Does closing the BufferedReader/PrintWriter close the socket connection?关闭 BufferedReader/PrintWriter 是否会关闭套接字连接?
【发布时间】:2009-01-27 19:46:50
【问题描述】:

我有一个应用程序,它使用简单的套接字在两个系统之间传递一些字符。我的 java 应用程序作为服务器运行。我建立了良好的连接,甚至传递了一条消息。但是,在发送了一条消息后,我的连接将关闭。

据我所知,似乎在关闭printWriterbufferedReader 时,套接字本身正在关闭?!这很糟糕,因为我要在同一个连接上发送多条消息。

printWriter = new PrintWriter(theServer.getClientSocket().getOutputStream());
bufferedReader = new BufferedReader(new InputStreamReader(theServer.getClientSocket().getInputStream()));


printWriter.println("the line");

printWriter.close(); //Closing on these lines?
bufferedReader.close(); //Closing on these lines?

我吃饱了吗?如何在 Java 中维护这种连接?

【问题讨论】:

标签: java sockets


【解决方案1】:

是的,关闭任何 Writer/Reader 将关闭它们包装的所有其他 Writer 和 Reader。在准备好关闭底层套接字之前不要关闭它。

【讨论】:

  • 我需要刷新缓冲区吗?我可以不用这些行并按照上面的代码继续使用套接字吗?
  • 如果您想控制线路何时触及电线,则需要冲洗。
  • 关闭是隐式刷新。如果你想在调用 close 之前刷新,那么一定要调用 flush。
  • 在使用 Reader/Writers 时请注意,如果您要使用恒定打开的套接字来回传输数据,我将保存对您的 reader 和 writer 对象的本地引用。创建。我每次都在创建它们,但引用相同的套接字并且有巨大的内存泄漏。更新为仅在套接字更改时创建并重用对象,泄漏消失了。由于内存泄漏,我发现了这篇文章,这有助于解决它。
【解决方案2】:

作为@Eddie said(比我早!:)),关闭编写器和/或读取器将关闭底层套接字流and the socket itself但是,我相信套接字本身不会关闭

关闭返回的 InputStream 将关闭关联的套接字。

您不应该关闭作者或读者。只需刷新作者以确保您的消息及时到达。稍后关闭套接字将关闭相应的流,因此您不需要自己关闭它们。只需将您的读取器/写入器对象留给 GC。

【讨论】:

【解决方案3】:

另一种选择是自己创建一个 NoCloseInputStream 和 NoCloseOutputStream 过滤器,它们在关闭时什么也不做;然后使用它们来包装您的应用程序套接字的流(在任何应用程序包装之前,如缓冲区)。

请注意,如果要执行此操作,则需要保留对套接字(或包装的流)的引用,以便在实际完成时关闭套接字。

回答“对于 OP 来说这个概念太高级”的评论:OP 的问题是在关闭顶级流时,他也在关闭底层套接字,但这并不好,因为他想进一步创建套接字上的顶级流以发送更多消息。根据他的架构,实现此目的的唯一方法可能是将流包装在 NoClose 包装器中 - 例如,他可能会将流传递给 XML 序列化器或反序列化器,后者在完成时关闭流,关闭不在他的控制范围内.

【讨论】:

  • 我相信这个答案对于这个问题来说太高级了。在我看来,它只会让 OP 感到困惑。
  • @SoftwareMonk 与其使用 NoCloseInputStream 做点什么,不如简单地刷新流并让它保持打开状态,直到您需要关闭底层套接字?
  • @Pacerier:因为,正如我所说,除其他外,一些设计糟糕的库,例如 Java 中内置的 XML 实现,会无条件地关闭任何给定的流。您可能还需要几层包装,并且能够关闭所有这些,直到基础套接字继续使用套接字而不是包装器。正如我所说,“另一种选择是......”
【解决方案4】:

关闭流后需要关闭套接字。

【讨论】:

猜你喜欢
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 2015-08-31
  • 1970-01-01
  • 2016-08-03
  • 2013-07-17
  • 2013-05-15
相关资源
最近更新 更多