Found different in behavior of SocketInputStream#read in JDK13

Chris Hegarty chris.hegarty at oracle.com
Wed Jul 31 22:58:01 UTC 2019


There may be a minor JDK issue here ...

Below is a minimal test, which I believe replicates the scenario that
the Zoo Keeper test finds itself in. The test exhibits the reported
behaviour; `read` returns -1 with the new nio socket impl, while throws
with the old plain socket impl.

The following, as of yet untested, change restores the behaviour
difference.

--- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java
+++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java
@@ -894,7 +894,7 @@
             // shutdown output when linger interval not set to 0
             try {
                 var SO_LINGER = StandardSocketOptions.SO_LINGER;
-                if ((int) Net.getSocketOption(fd, SO_LINGER) != 0) {
+                if ((int) Net.getSocketOption(fd, SO_LINGER) > 0) {
                     Net.shutdown(fd, Net.SHUT_WR);
                 }
             } catch (IOException ignore) { }


The change in behaviour comes from the `close` on the server-side
shutting down the output before closing the socket. When debugging this
issue the linger value being returned ( on my mac ) is -1, meaning that
the option is disabled.

I'll need to do some testing on the above patch, but on the face of it
I believe that `shutdown` should only be called if the linger value is
positive.

---

public class Zoo {

    public static void main(String... args) throws Exception {
        try (ServerSocket ss = new ServerSocket(0)) {

            Thread t = new Thread() {
                @Override
                public void run() {
                    try {
                        Socket s = ss.accept();
                        byte[] ba = new byte[5];
                        int r = s.getInputStream().read(ba);
                        assert r == 5;
                        s.close();
                    } catch (IOException e) {
                        throw new UncheckedIOException(e);
                    }
                }
            };
            t.start();

            int port = ss.getLocalPort();
            Socket s = new Socket("localhost", port);
            byte[] ba = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05,
                                     0x06, 0x07, 0x08, 0x09, 0x10  };
            s.getOutputStream().write(ba);
            int r = s.getInputStream().read();
            System.out.println("read: " + r);
        }
    }
}

-Chris.




More information about the nio-dev mailing list