简体   繁体   English

为什么我只能先关闭socket的输出流再关闭输入流?

[英]Why I can only close socket's outputStream first and then close inputstream?

I wrap a socket.getInputStream() by an InputStreamReader, and wrap a socket.getOutputStream() by an OutputStreamWriter.我用 InputStreamReader 包装 socket.getInputStream(),用 OutputStreamWriter 包装 socket.getOutputStream()。 I find that the closing order of these streams really matters but I didn't figure out why.我发现这些流的关闭顺序确实很重要,但我不知道为什么。

If I close the outputStream first and then close the inputStream, it works fine:如果我先关闭 outputStream 然后关闭 inputStream ,它工作正常:

outputStreamWriter.close();
inputStreamReader.close();

However, if I close the inputStream first and then close the outputStream, it throws an error:但是,如果我先关闭 inputStream,然后关闭 outputStream,则会引发错误:

inputStreamReader.close();
outputStreamWriter.close();

The error is:错误是:

java.net.SocketException: Socket closed
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118)
    at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
    at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
    at sun.nio.cs.StreamEncoder.implClose(StreamEncoder.java:316)
    at sun.nio.cs.StreamEncoder.close(StreamEncoder.java:149)
    at java.io.OutputStreamWriter.close(OutputStreamWriter.java:233)
    at http.HTTPServer.start(HTTPServer.java:69)
    at http.HTTPTest.main(HTTPTest.java:10)

Also, I want to ask do I still need to call socket.close() after closing the socket's inputstream and output stream?另外,我想问一下在关闭socket的输入流和output stream之后还需要调用socket.close()吗? And if I close the socket first, do I still need to close these two streams?如果我先关闭套接字,我还需要关闭这两个流吗?

From Socket.close()Socket.close()

Closing this socket will also close the socket's InputStream and OutputStream .关闭此套接字也将关闭套接字的InputStreamOutputStream

From Socket.getInputStream()Socket.getInputStream()

Closing the returned InputStream will close the associated socket.关闭返回的InputStream将关闭关联的套接字。

From Socket.getOutputStream()Socket.getOutputStream()

Closing the returned OutputStream will close the associated socket.关闭返回的OutputStream将关闭关联的套接字。

So you can't close just one stream intentionally or accidentally.因此,您不能有意或无意地只关闭一个 stream。 If you're done with the socket, then Socket.close() is fine.如果您完成了套接字,那么Socket.close()就可以了。 Although if you're using try-with-resources then the streams may get closed automatically anyway.尽管如果您使用的是 try-with-resources,那么流可能会自动关闭。 Depends on your design how to write the logic.取决于您的设计如何编写逻辑。

The reason for the exception here is OutputStreamWriter buffering bytes, so when you close() it writes out its buffer first (if buffer is not empty).这里异常的原因是OutputStreamWriter缓冲字节,所以当你close()它首先写出它的缓冲区(如果缓冲区不为空)。 If you close the writer first, the socket is still open and the bytes will be written, if you close the reader first the socket is closed and you get an exception.如果你先关闭 writer,socket 仍然是打开的,字节会被写入,如果你先关闭 reader,socket 就会关闭,你会得到一个异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我可以关闭servlet中的包装输入流或输出流类吗? - Can I close wrapper inputstream or outputstream class in servlet? 如何在保持输入流打开的同时关闭 Java 套接字的输出流以获得结果? - How to close a Java's socket's outputstream while keeping the inputstream open to get a result? 如果关闭BluetoothSocket,是否需要关闭InputStream / OutputStream? - do I need to close InputStream/OutputStream if I close BluetoothSocket? 套接字关闭与输入流关闭 - Socket close vs Inputstream close 为什么关闭()输入流是好的? - Why is it good to close() an inputstream? 使用Java ProcessBuilder运行haskell可执行文件:为什么hGetLine仅在关闭outputStream时返回? - Running haskell executable using Java ProcessBuilder: Why does hGetLine only return when I close outputStream? 仅当我关闭Eclipse应用程序时才输出输出流 - Outputstream write only when I close Eclipse Application 我可以关闭并重新打开套接字吗? - Can I close and reopen a socket? 套接字输出流和输入流的问题 - Problems with socket outputstream and inputstream 我可以关闭基础输出流并让装饰器BufferedOutputStream处于未关闭状态吗 - Can I close underlying outputstream and let the decorator BufferedOutputStream unclosed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM