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

(se) Using OP_CONNECT with Selector.select causes selector to fire repeatedly

XMLWordPrintable

    • x86
    • linux, windows_xp

      Name: dk106046 Date: 11/27/2003

      java version "1.4.2"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
      Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)



      /* This testcase illustrates a problem with non-blocking connection to a server.
      We start a simple server, listening on port 8765, which just accepts
      connections. We then register a non-blocking SocketChannel (the client) with a
      selector with interest in OP_CONNECT, so that we can use the selector to notify
      us when the channel is ready to finish connecting. We call client.connect and
      then selector.select in a loop. The selector fires and with the client channel
      in the selected-keys set and we call finishConnect() on the client's channel.
      Then the problem occurs: the selector repeatedly fires with no entries in its
      selected-keys set, whereas it should block in the next select operation until
      there is at least one key in the selected-keys set. */

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

      public class OpConnectTest {

          public static int PORT = 8765;

          public static void main( String[] args ) {
              new OpConnectTest() . runTest();
          }

          /* Start a server running in a separate thread. Wait for it to start then
          do a non-blocking connect to it. */
          public void runTest() {
              try{
                  new Thread( new Runnable() {
                      public void run() {
                          new AcceptServer() . startServer();
                      }
                  } ) . start();
                  // Give the server enough time to start up.
                  Thread.sleep( 200 );
                  connectNonBlockingClient();
                  connectFinished = true;
              } catch ( Exception e ) {
                  System.out.println( e );
              }
          }

          public static boolean connectFinished = false;

          /* Create a SocketChannel, register it with a Selector for OP_CONNECT, then
          do a non-blocking connect. */
          public void connectNonBlockingClient() throws Exception
          {
              SocketChannel channel = SocketChannel.open( );
              channel.configureBlocking( false );

              Selector selector = Selector.open();
              channel.register( selector, SelectionKey.OP_CONNECT );
              
              channel.connect( new InetSocketAddress( "localhost", PORT ) );

              for ( int j=1; j < 10; j++ ) {
                  selector.select();
                  System.out.println( "selector.SelectedKeys().size() = "
                                     + selector.selectedKeys().size() );
                  
                  Iterator i = selector.selectedKeys().iterator();
                  while ( i.hasNext() ) {
                      SelectionKey key = (SelectionKey)i.next();
                      i.remove();
                      try {
                          if ( ((SocketChannel)key.channel()).finishConnect() )
                              System.out.println( "connected" );
                          else
                              System.out.println( "not connected" );
                      } catch ( ConnectException e ) {
                          System.out.println( "encountered problem connecting" );
                          throw e;
                      }
                      System.out.println( "key.isValid() = " + key.isValid()
                        + ", key.channel().isOpen() = " + key.channel().isOpen() );
                  }
              }
          }
      }

      class AcceptServer {
          public void startServer() {
              try{
                  ServerSocketChannel server = ServerSocketChannel.open();
                  server.configureBlocking( false );
                  System.out.println( "Starting AcceptServer listening on port "
                                     + OpConnectTest.PORT );
                  server.socket().bind( new InetSocketAddress( OpConnectTest.PORT ) );
                  while ( !OpConnectTest.connectFinished ) {
                      server.accept(); // Accept connection, then do nothing with it.
                  }
              } catch ( Exception e ) {
                  System.out.println( e );
              }
          }
      }


      ======================================================================

            sherman Xueming Shen
            dkorbel David Korbel (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: