Sunday, May 22, 2011

Creating Non-Blocking Client and Server with Java NIO

With Java NIO, creating non-blocking client and server is pretty straightforward. Below is a sample code how to do that.

HelloServer.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;

public class HelloServer {
    private static final String HELLO_REPLY = "Hello World!";
    
    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.wrap(HELLO_REPLY.getBytes());
        ServerSocketChannel ssc = null;
        try {
            ssc = ServerSocketChannel.open();
            ssc.socket().bind(new InetSocketAddress(8888));
            ssc.configureBlocking(false);
            
            while (true) {
                SocketChannel sc = ssc.accept();
                // if sc == null, that means there is no connection yet
                // do something else
                if (sc == null) {
                    // pretend to do something useful here
                    System.out.println("Doing something useful....");
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                } else { // received an incoming connection
                    System.out.println("Received an incoming connection from " +
                        sc.socket().getRemoteSocketAddress());
                    printRequest(sc);
                    buffer.rewind();
                    sc.write(buffer);
                    sc.close();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ssc != null) {
                try {
                    ssc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    private static void printRequest(SocketChannel sc) throws IOException {
        ReadableByteChannel rbc = Channels.newChannel(
            sc.socket().getInputStream());
        WritableByteChannel wbc = Channels.newChannel(System.out);
        ByteBuffer b = ByteBuffer.allocate(8); // read 8 bytes 
        while (rbc.read(b) != -1) {
            b.flip();
            while (b.hasRemaining()) {
                wbc.write(b);
            }
            b.clear();
        }
    }
}

HelloClient.java
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;

public class HelloClient {
    public static final String HELLO_REQUEST = "Hello!";
    public static void main(String[] args) {
        SocketChannel sc = null;
        try {
            sc = SocketChannel.open();
            sc.configureBlocking(false);
            // make sure to call sc.connect() or else 
            // calling sc.finishConnect() will throw 
            // java.nio.channels.NoConnectionPendingException
            sc.connect(new InetSocketAddress(8888));
            // if the socket has connected, sc.finishConnect() should 
            // return false
            while (!sc.finishConnect()) {
                // pretend to do something useful here
                System.out.println("Doing something useful...");
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("Sending a request to HelloServer");
            ByteBuffer buffer = ByteBuffer.wrap(HELLO_REQUEST.getBytes());
            sc.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (sc != null) {
                try {
                    sc.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

4 comments:

  1. hello sir ........
    very valuable post. . . priceless actually am building a chatt apllication using java nio. this post helped me a lot thank you very much. . . .

    keep posting

    ReplyDelete
  2. Awesome man, this is exactly what I needed thanks :-)

    ReplyDelete
  3. It's really helpful for me. :)
    Can you please use selector in above example!

    ReplyDelete