Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4697142

New nio SocketChannel writes do not seem to flush to old style JDK Sockets

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P3 P3
    • None
    • 1.4.0
    • core-libs
    • x86
    • windows_2000



      Name: nt126004 Date: 06/04/2002


      FULL PRODUCT VERSION :
      java version "1.4.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
      Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)


      FULL OPERATING SYSTEM VERSION :
      Windows 2000 SP 2

      A DESCRIPTION OF THE PROBLEM :
      The new nio SocketChannel API writes don't seem to flush
      correctly to old JDK 1.3 Sockets. We have an existing
      client application that connects to a server that's being
      rearchitected to use nio non-blocking sockets. The JDK 1.3
      client hangs on reads from the server. We've verified that
      all writes are being sent through the socket channel.

      I've written a quickie test case.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1. Run nio_server in a 1.4 java VM on Windows 2000.

      2. Run blocking_client in a 1.3 java VM on Windows 2000.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      The client should print "n. Waiting." and then a
      corresponding "n. Done." forever. Early on in the run, the
      Waits will get hung. However, when I use old-style server
      code, it never hangs. Further, if I use a new-style nio
      client, it never hangs.

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      Here's a canned JDK 1.4 server. Run under JDK 1.4:

      import java.nio.*;
      import java.nio.channels.*;
      import java.net.*;
      import java.io.*;
      import java.util.*;

      public class nio_server
      {
      public static void main(String[] args) throws Exception
      {
      Selector selector = Selector.open
      ();
      ServerSocketChannel server = ServerSocketChannel.open();
      server.configureBlocking(false);
      InetSocketAddress address = new InetSocketAddress(10064);
      server.socket().bind(address);
      server.register(selector, SelectionKey.OP_ACCEPT);

      for(;;)
      {
                  if ( selector.select() > 0 )
      {
      Iterator iterator = selector.selectedKeys().iterator();
      while ( iterator.hasNext() )
      {
      SelectionKey key = (SelectionKey) iterator.next();
      iterator.remove();

      if ( key.isAcceptable() )
      {
                              SocketChannel socket = server.accept();
      socket.configureBlocking(false);

      SelectionKey
      socket_key = socket.register(selector, SelectionKey.OP_READ |
      SelectionKey.OP_WRITE);

      socket_holder holder = new socket_holder(socket);
      socket_key.attach(holder);
      }
      else if ( key.isReadable() )
      {
                              socket_holder holder = (socket_holder)
      key.attachment();
      holder.do_read();
      }
      }
      }
      }
      }

      private static class socket_holder
      {
      public socket_holder(SocketChannel socket)
      {
      socket_mbr = socket;
      }

      public void do_read() throws IOException
      {
                  ByteBuffer buffer = ByteBuffer.allocate(1024);
      read_loop: for(;;)
      {
      buffer.clear();
      socket_mbr.read(buffer);

      buffer.flip();
      for ( int i = 0; i < buffer.limit(); ++i )
      {
      if ( (char)(buffer.get(i) & 0xff)
      == '\n' )
      {
      break read_loop;
      }
      }
      }

      buffer = ByteBuffer.allocate(32767);
      for ( int i = 0; i < buffer.capacity() - 1; ++i )
      {
      buffer.put((byte)('a' & 0xff));
      }
      buffer.put((byte)('x' & 0xff));
      buffer.rewind();

      while ( buffer.hasRemaining() )
      {
      socket_mbr.write(buffer);
      }
      }

      private SocketChannel socket_mbr;
      }
      }


      Here's a JDK 1.3 client. Run under JDK 1.3:

      import java.net.*;
      import java.io.*;
      import java.util.*;
      public class blocking_client
      {
      public static void main(String[] args) throws Exception
      {
      for ( int i = 0; i < 10; ++i )
      {
      final int index = i;
      Thread a_thread = new Thread()
      {
      public void run()
      {
      Random
      r = new Random(System.currentTimeMillis());
      for(;;)
      {
      try
      {
      Thread.sleep(r.nextInt
      (500));
      }
      catch ( InterruptedException e )
      {
      }

      try
      {
      do_it(index);
      }
      catch ( IOException e )
      {
      e.printStackTrace();
      }
      }
      }
      };
      a_thread.start();
      }
      }

      private static void do_it(int index) throws IOException
      {
      Socket s = new Socket
      ("localhost", 10064);
      PrintStream out = new PrintStream
      (new BufferedOutputStream(s.getOutputStream()));
      InputStream in = new
      BufferedInputStream(s.getInputStream());

      out.print("x\r\n");
      out.flush();

      System.out.println(index + ". Waiting.");
      for(;;)
      {
      int b = in.read();
      char c = (char)(b & 0xff);
      if ( c == 'x' )
      {
      break;
      }
      }
      System.out.println(index + ". Done.");
      }
      }

      ---------- END SOURCE ----------
      (Review ID: 145803)
      ======================================================================

            mmcclosksunw Michael Mccloskey (Inactive)
            nthompsosunw Nathanael Thompson (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: