BufferedOutputStream.close() 会让 BufferedInputStream 被关闭?

Posted

技术标签:

【中文标题】BufferedOutputStream.close() 会让 BufferedInputStream 被关闭?【英文标题】:BufferedOutputStream.close() will let BufferedInputStream be closed? 【发布时间】:2017-10-13 11:33:06 【问题描述】:

这是我第一次使用套接字程序。 我的要求是android客户端提出问题并通过套接字从ubuntu服务器接收答案。 在我的客户端,我从我的套接字创建了 BufferedInputStream 和 BufferedInputStream。

Socket client = new Socket();
InetSocketAddress isa = new InetSocketAddress(my_host, 8888);
client.connect(isa, 10000);
inputStream = new BufferedInputStream(client.getInputStream());
outputStream = new BufferedOutputStream(client.getOutputStream());

我遇到了一个奇怪的行为:当我的客户端通过 outputStream 发送请求并调用它的 close() 时,调用 inputStream.read() 将得到 java.net.SocketException: Socket is closed 错误。但是我的 client.isConnected() 仍然返回 true。

try 
  outputStream.write("who_are_you".getBytes());
  outputStream.flush();
  outputStream.close();  // inputStream will be invalid if I call this line.

  Log.i(TAG, "client: " + client.isConnected());  // client still return true
  byte[] b = new byte[1024];
  String data = "";
  int length;
  // I will receive java.net.SocketException: Socket is closed as I call below code
  while ((length = inputStream.read(b)) > 0)  // If length <= 0, it means exit.
  
    Log.i(TAG, "receive message, length: " + length);
    data += new String(b, 0, length);
    Log.i(TAG, "receive message: " + data);
  
 catch (java.io.IOException e) 
  Log.w(TAG, "socket connection fail");
  e.printStackTrace();

我知道如果我不调用 outputStream.close() 可以避免这种情况。但我只是很好奇为什么会这样?结果正常吗?

【问题讨论】:

是的,如果您关闭一个流,其他流也将关闭。还有插座。 在 finally 块中关闭你的流 是否检查过服务器是否意外关闭了连接? 【参考方案1】:

关闭套接字输入流或输出流将在套接字本身上调用 close。所以你不需要关闭它们,除非你想关闭连接。

关于您的检查,请参阅Socket#isConnected() 方法上的 javadoc (https://docs.oracle.com/javase/7/docs/api/java/net/Socket.html#isConnected())

公共布尔isConnected()

返回套接字的连接状态。

注意:关闭套接字并不会清除其连接状态,这意味着如果在关闭之前已成功连接,则此方法将为已关闭的套接字返回 true(参见 isClosed())。

【讨论】:

以上是关于BufferedOutputStream.close() 会让 BufferedInputStream 被关闭?的主要内容,如果未能解决你的问题,请参考以下文章