Why does socket.isOutputShutdown () return false even if the socket is closed?

The Java Socket API tells me that closing a socket also closes the socket InputStreamand OutputStream.

Neither the Javadoc Socket API nor the I / O API information can determine (I have not found it yet), which means shutdown for OutputStreamor InputStream, but I assumed that shutting down either puts them in a shutdown state.

However, after I successfully called my client socket method close()(the call isClosed()returns true), if I then call either the socket method isInputShutdown()or isOutputShutdown(), the result will be false.

I am sure that no thread has unread / unsent data buffered during a Socket call close().

I assume I don't understand what “shutdown” means for socket I / O streams, and / or when shutting down.

+4
source share
3 answers

Even after calling socket.getOutputStream (). close () calling socket.isOutputShutdown () returns false. Also, if the socket is not connected yet, socket.isOutputShutdown () will return false.

Invokation socket.isOutputShutdown () ONLY returns true when socket.shutdownOutput () was previously called. You are right that the document is a little misleading in this matter.

, socket.shutdownOutput() . ( , , , ).

+3

TL; DR

, true isOutputShutdown shutdownOutput . Socket. , true, .


- ;)

isOutputShutdown java.net.Socket:

public boolean isOutputShutdown() {
    return shutOut;
}

, , shutOut. , true shutdownOutput ( )

public void shutdownOutput() throws IOException
{
    if (isClosed())
        throw new SocketException("Socket is closed");
    if (!isConnected())
        throw new SocketException("Socket is not connected");
    if (isOutputShutdown())
        throw new SocketException("Socket output is already shutdown");
    getImpl().shutdownOutput();
    shutOut = true;
}

, SocketException, , , Socket . getImpl, , , shutdownOutput .

SocketImpl getImpl() throws SocketException {
    if (!created)
        createImpl(true);
    return impl;
}

javadoc , SocketImpl, . , , . SocketImpl - , , shutdownOutput.

, factory instance

factory.createSocketImpl()

, SocketImplFactory. - SocketImpl createSocketImpl();. SicketImpl, shutdownOutput?

AbstractPlainSocketImpl ( ), SocketImpl. javadoc - . , . , , , shutdownOutput.

/**
 * Shutdown read-half of the socket connection;
 */
protected void shutdownInput() throws IOException {
  if (fd != null) {
      socketShutdown(SHUT_RD);
      if (socketInputStream != null) {
          socketInputStream.setEOF(true);
      }
      shut_rd = true;
  }
}

/**
 * Shutdown write-half of the socket connection;
 */
protected void shutdownOutput() throws IOException {
  if (fd != null) {
      socketShutdown(SHUT_WR);
      shut_wr = true;
  }
}

, ? fd socketShutdown.

! SHUT_WR?

, @EJP, API Berkeley Sockets. , (0 , 1 )

public final static int SHUT_RD = 0;
public final static int SHUT_WR = 1;

socketShutdown,

abstract void socketShutdown(int howto)
    throws IOException;

, , ...

, PlainSocketImpl, AbstractPlainSocketImpl.

native void socketShutdown(int howto) throws IOException;

java.net.PlainSocketImpl.c .

Java_java_net_PlainSocketImpl_socketShutdown(JNIEnv *env, jobject this,
                                           jint howto)
{

  jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
  jint fd;

  /*
   * WARNING: THIS NEEDS LOCKING. ALSO: SHOULD WE CHECK for fd being
   * -1 already?
   */
  if (IS_NULL(fdObj)) {
      JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
                      "socket already closed");
      return;
  } else {
      fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
  }
  JVM_SocketShutdown(fd, howto);
}

, , .

"" OutputStream InputStream

isOutputShutdown false, isClosed true?

, , shutOut boolean true shutdownOutput

public void shutdownOutput() throws IOException
{
    if (isClosed())
        throw new SocketException("Socket is closed");
    if (!isConnected())
        throw new SocketException("Socket is not connected");
    if (isOutputShutdown())
        throw new SocketException("Socket output is already shutdown");
    getImpl().shutdownOutput();
    shutOut = true;
}

, Socket boolean true. false, , , Socket the Stream .

+2

shutdownOutput() FIN , peer .

shutdownOutput(), isOutputShutdown() true. false.

:

  • shutdownInput() isInputShutdown()
  • close() isClosed()
  • connect() new Socket(...) isConnected().

API , API. - isBound(), , bind() connect() new Socket(...) ServerSocket.accept().

And not one of them changes state depending on what peer does with the connection. In particular, isClosed()does not mean that the peer has closed the connection. This means that you have closed this connector.

+1
source

All Articles