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

SocketChannel.write(ByteBuffer src) hangs in Redhat Linux 7.2

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Not an Issue
    • Icon: P4 P4
    • None
    • 1.4.0
    • core-libs
    • x86
    • linux



      Name: nt126004 Date: 02/22/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 :Linux RedHat 7.2


      A DESCRIPTION OF THE PROBLEM :
      I try to use following codes to delivery a file from a
      Linux machine. When the size of file is larger than 64K
      bytes,the program is stuck. Howerver,the same program is
      working fine at a windows 2000 Advanced Server machine.



      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      No error message.


      STEPS TO REPRODUCE:
      1.Install Red Hat 7.2 on a computer .
      2.Download Java 1.4 RPM package and install it.
      3.Prepare a large file(test.txt) and put the file into the same directory as
      SampleServer.
      3.Run SampleServer.
      4.Run telnet to port 9988 at same machine.

        You should be getting the content of whole test.txt file. However,you will
      only get part of the file.The server will hang at some place in the file
      while sending the data. Each time you hit "Enter" another request for
      getting the file will be sent to the server.All requests after the first
      will complete without problem.

      If you telnet from Windows or Solaris machine, all requests will hang at same
      place in the middle of file.

      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.io.*;
      import java.nio.*;
      import java.nio.channels.*;
      import java.nio.channels.spi.*;
      import java.nio.charset.*;
      import java.net.*;
      import java.util.*;

      /**
      * Using Java Merlin's new i/o package to deliver a nonblocking server.
      */
      public class SampleServer implements Runnable {
          private static final int PORT=9988;
          private int port = PORT;
          private Selector selector = null;
          private ServerSocketChannel selectableChannel = null;
          private int keysAdded = 0;
          private boolean connectionIsMade=false;
          private InetAddress lh;
          private Thread thread;
      /**
      * Create a rais server by using default parameters.
      * web directory=c:\\temp
      */
       public SampleServer() {
       }
      /**
      * Initializes selector and specifies the channel to nonblocking =
      states.
      */
      public void initialize() throws IOException {
          this.selector = SelectorProvider.provider().openSelector();
          this.selectableChannel = ServerSocketChannel.open();
          this.selectableChannel.configureBlocking(false);
          lh = InetAddress.getLocalHost();
          InetSocketAddress isa = new InetSocketAddress(this.port );
          this.selectableChannel.socket().bind(isa);
       }
      /**
      * close channel and selector before the object is been destoried.
      */
      public void finalize() throws IOException {
          this.selectableChannel.close();
          this.selector.close();
      }
      /**
      * Begins to accept connections which are come from clients.
      */
      public void acceptConnections()throws IOException, InterruptedException {
          selectableChannel.register(selector,SelectionKey.OP_ACCEPT);
              SelectionKey acceptKey = selectableChannel.register(selector,
                                                    SelectionKey.OP_ACCEPT);
          System.out.println( "Waiting for connection......" );
          connectionIsMade=false;
          while (( this.keysAdded = acceptKey.selector().select()) > 0 ) {
                  Set readyKeys = this.selector.selectedKeys();
                  Iterator i = readyKeys.iterator();
                  while (i.hasNext()) {
                      SelectionKey key = (SelectionKey)i.next();
                      i.remove();
                      if ( key.isAcceptable() ) {
                                              System.out.println("accepting a connection");
                          ServerSocketChannel nextReady = (ServerSocketChannel)key.channel();
                          SocketChannel channel = nextReady.accept();
                          channel.configureBlocking( false );
                          SelectionKey readKey = channel.register( this.selector,
                                  SelectionKey.OP_READ|SelectionKey.OP_WRITE);
                          readKey.attach( new ChannelCallback( channel ) );
                      }
                      else if ( key.isReadable() ) {
                                              System.out.println("reading a message");
                          this.readMessage( (ChannelCallback) key.attachment() );
                      }
                      else if ( key.isWritable() && !connectionIsMade) {
                                              connectionIsMade=true;
                          ChannelCallback callback = (ChannelCallback) key.attachment();
                      }
                  }

              }
              System.out.println( "End acceptor loop..." );
          }

              public static void main (String args[])
                      { SampleServer S=new SampleServer();
                        S.start();
                  }


         /**
         * Sends a file to client.
         * @param channel current channel.
         * @param filename file to be sent.
         */
          public void writeFile(SocketChannel channel,String filename) throws
      IOException{

                      System.out.println("writeFile()");
                  ByteBuffer[] bf=new ByteBuffer[2];
                  String message="226 transfer completed.\r\n";
              bf[1]= ByteBuffer.wrap( message.getBytes() );

                  try{
                     FileInputStream fis = new FileInputStream(new File(filename));
                         FileChannel fc = fis.getChannel();
      // Get the file's size and then map it into memory
                         int sz = (int)fc.size();
                         bf[0]=fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
                 channel.write( bf );//Due to the nonblocking,I have to send = data and message togather
                 fc.close();
              }catch(FileNotFoundException e){
                      }
              }


          private String decode( ByteBuffer byteBuffer )
          throws CharacterCodingException {
              Charset charset = Charset.forName( "us-ascii" );
              CharsetDecoder decoder = charset.newDecoder();
              CharBuffer charBuffer = decoder.decode( byteBuffer );
              String result = charBuffer.toString();
              return result;
          }


      /**
      * Reads an message from client.
      * @param callback callback object.
      */
          static final int BUFSIZE = 8;

          public void readMessage( ChannelCallback callback )
          throws IOException, InterruptedException {
              ByteBuffer byteBuffer = ByteBuffer.allocate( BUFSIZE );
              int nbytes = callback.getChannel().read( byteBuffer );
              byteBuffer.flip();
              String result = this.decode( byteBuffer );
      // System.out.println( result );

              callback.append( result.toString() );
              if ( result.indexOf( "\n" ) >= 0 )
                      callback.execute();

          }
      /**
      * Start this class as a thread.
      */
          public void start() {
                  thread = new Thread(this);
                  thread.setPriority(Thread.MIN_PRIORITY);
                  thread.setName("RaisServer");
                  thread.start();
              }
              /**
              * Stops the current thread.
              */
          public synchronized void stop() {
             thread=null;
             notify();
             try{finalize();}catch(IOException e){}
             System.out.println("Server is down.");
          }
              /**
              * Run method.
              */

          public void run(){
              Thread me=Thread.currentThread();
              try {
                  initialize();
              } catch ( IOException ioe ) {
                  ioe.printStackTrace();
                  System.exit( -1 );

              }
              while (thread == me ) {
                  try {
                     acceptConnections();
                  }
                  catch ( IOException e ) {
                     e.printStackTrace();
                     System.out.println( e );
                  }
                  catch ( InterruptedException e ) {
                     System.out.println( "Exiting normally..." );
                     break;
                  }
              }

      }
      /**
      * Inner class to define a class back object for manipulate multil =
      users.
      */
      class ChannelCallback {
              private SocketChannel channel;
              private StringBuffer buffer;
      /**
      * Constructor.
      * @param channel current returned channel.
      */
         public ChannelCallback( SocketChannel channel ) {
              this.channel = channel;
              this.buffer = new StringBuffer();
         }
         /**
         * Executes the commands which are come from clients.
         */
         public void execute() throws IOException, InterruptedException {
                      System.out.println("execute");
              String commandstr=buffer.toString();
              writeFile(channel,"test.txt");
              buffer = new StringBuffer();
         }
      /**
      * Returns current channel.
      */
         public SocketChannel getChannel() {
              return this.channel;
         }
      /**
      * Appends reading string to buffer for future processing.
      */
         public void append( String values ) {
              buffer.append( values );
         }
      }
      }

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

            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: