关闭输出流时Java套接字的行为

有人可以解释Java套接字中的以下行为:

一般的想法是这样的:

  1. 打开套接字,获取I / O流。
  2. 写请求,关闭流
  3. 读取响应,在流中关闭
  4. 关闭sockets。

这是我的问题/问题。

如果我使用PrintWriter进行输出,然后将其关闭,它会关闭整个套接字,后续的读操作会失败。

相反,如果我直接使用套接字的shutdownOutput()方法,它会正确关闭输出流通道,同时保持套接字处于活动状态。

为什么关闭PrintWriter对象会占用整个套接字?

这可能是您的代码的样子:

 Socket socket; PrintWriter pw = new PrintWriter(socket.getOutputStream()); pw.close(); 

现在,让我们看一下Socket的getOutputStream()方法的描述。

getOutputStream

public OutputStream getOutputStream() throws IOException

返回此套接字的输出流。 如果此套接字具有关联的通道,则生成的输出流将其所有操作委托给通道。 如果通道处于非阻塞模式,则输出流的写入操作将抛出IllegalBlockingModeException

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

返回:

用于将字节写入此套接字的输出流。

抛出:

IOException – 如果在创建输出流时发生I / O错误或者未连接套接字。

从上面的描述中,我们知道关闭返回的OutputStream将关闭相关的套接字。

现在,当您关闭PrintWriter ,它将关闭关闭的OutputStream ,它将关闭相关的套接字。

这可能是因为调用PrintWriterclose()方法正在追溯层次结构并调用SocketOutputStreamclose()方法。 作为SocketOutputStreamclose()方法的SocketOutputStream它也为Socket调用close()方法,这也将关闭SocketInputStream 。 调用shutdownOutput()函数会发送任何先前写入的数据,然后发送TCP的正常连接终止序列。 然后它禁用输出流。