Multiple non-blocking selectors in threads

About networking in java and sockets i read alot. I know about the 2 implementations witk thread per client and non-blocking IO (usage of select()). I ran a few tests of my own and i could't decide. So I wrote a server that uses them both. The Ideea is to have no more than 100 clients per each selector and each selector runs in a thread. so when you have 4000 clients you actualy have 40 threads running each 100 clients:D
However I'm stuck. I wrote this piece of code that has 2 objects one work thread with his own selector and a main thread with an accepting selector. The problem is that when I connect to it via telnet it only works when there is an even number of clients:(( when client nr 1 connects it blocks on channel.register(workSelector,SelectionKey.OP_READ);when client 2 gets connected it works:((
HELP!!!
here is the
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
//work thread with own selector
class workThread implements Runnable{
     public int userCount=0;
     public int ID=0;
     private Charset charset;
     private CharsetEncoder encoder;
     private CharsetDecoder decoder;
     private ByteBuffer buffer;
     private ConcurrentHashMap userMap;
     public Selector workSelector = null;
     public void addClient(SelectableChannel channel, int ops) throws IOException{
          if (channel == null) return;
          //channel.configureBlocking(false);
          System.out.println("Channel was added in workSelector : "+channel);
          channel.register(workSelector,SelectionKey.OP_READ);
          System.out.println("Client was added in work selector : " + ID);
          userCount++;
          System.out.println("Client nr : "+userCount);
     public boolean find(String name){
          return true;
     public workThread() throws IOException{
          charset = Charset.forName("ISO-8859-1");
          encoder = charset.newEncoder();
          decoder     = charset.newDecoder();     
          buffer = ByteBuffer.allocate(256);
//          System.out.println("S-a creat selectorul");
          workSelector = Selector.open();
          System.out.println("Selector open ");
     private void doRead(SelectionKey key) throws IOException{
          SocketChannel clientChannel = (SocketChannel)key.channel();
          buffer.clear();
          System.out.println("Speaking to client");
          if(clientChannel.read(buffer) == -1){
               key.cancel();
               clientChannel.close();
          }else{
               buffer.flip();
               String message = decoder.decode(buffer).toString();
               System.out.println(message);
               if(message.trim().equals(".")){
                    clientChannel.write(encoder.encode(CharBuffer.wrap("BYE")));
                    key.cancel();
                    clientChannel.close();
               }else{
                    buffer.flip();
                    clientChannel.write(buffer);
     private void doWrite(SelectionKey key){
          System.out.println("WRITE!!!");
     public void run(){
          while(true){
               try{
               if(workSelector.select() > 0){
                    Set keys1 = workSelector.selectedKeys();
                    for(Iterator itr = keys1.iterator();itr.hasNext();){
                         SelectionKey key = (SelectionKey)itr.next();
                         itr.remove();
                         if(key.isReadable()) {doRead(key);}
                    //     if(key.isWritable()) {doWrite(key);}
          }catch(IOException e){
               System.out.println("Error in workthread "+ID+" "+e);
//main thread
public class msselect implements Runnable{
     private ServerSocketChannel server;
     private ServerSocket sock;
     private Selector acceptSelector;
     private workThread wk;
     public static void main(String args[]){
          try{
          msselect x = new msselect("80.97.89.73",6500,5);
          new Thread(x).start();
          }catch(IOException ex){
               System.out.println("Probleme"+ex);
     msselect(String host, int port, int numT) throws IOException{
          server = ServerSocketChannel.open();
          sock = server.socket();
          sock.bind(new InetSocketAddress(port));
          server.configureBlocking(false);
          acceptSelector = Selector.open();
          server.register(acceptSelector, SelectionKey.OP_ACCEPT);
/*          for(int i=0;i<numT;i++){
               wk[i] = new workThread();
               wk.ID = i;
               new Thread(wk[i]).start();
          wk = new workThread();
          wk.ID = 1;
          server.register(wk.workSelector, SelectionKey.OP_ACCEPT);
          new Thread(wk).start();
     public void run(){
          while(true){
               try{
               acceptSelector.select();
               Set keys = acceptSelector.selectedKeys();
               for(Iterator itr = keys.iterator();itr.hasNext();){
                    SelectionKey key = (SelectionKey)itr.next();
                    itr.remove();
                    if(key.isAcceptable()){
                         SocketChannel client = null;
                         client = server.accept();
                         client.configureBlocking(false);
                         System.out.println("Accepted "+client);
                         wk.addClient(client,SelectionKey.OP_READ);
          }catch(IOException e){
               System.out.println("Main Thread error"+e);

I compiled and ran your code.
The call channel.register(...) should block while selector is blocked in workSelector.select(). The fact that the registration succeeds is that you registered the server channel with both the work selector and the acceptor selector. The work selector is returning from select() because of a new client connection is accepted and is a matter of thread scheduling that the client.register() succeeeds (but only sometimes).
Possible solution:
- don't register the server channel with the work selector;
- probably call workSelector.wakeup() to make the client channel registration possible.

Similar Messages

  • Java.nio selector non-blocking IO question

    Hi,
    I am designing an interactive server where multiple clients can log on and communicate with the server. I designed a protocol that the client/server use to talk to each other. My server runs a Selector to monitor a ServerSocket, accepting connections and reading continuously from clients.
    Now my question is, since read() on ServerChannel are non-blocking using selector, how can I be sure that my entire protocol message will be read each time selector wakes up? For example, a slow client sends me a 5kb message, in one write() command, can I be sure that I will be able to read the entire message in one non-blocking read() command as well? If not, then the design becomes much more complicated, as I have to pipe each client's input into a handler thread that performs blocking i/o to read a protocol message one at a time. If I do that, then I might as well not use select() at all.
    I did some preliminary tests, and it seems that for my purpose (message of size <= 50kb), a read() command will always be able to read the entire message. But I can't find any documentation on this subject. My guess is that I cannot trust non-blocking I/O as well, which means it does not fit my purpose.
    Any help will be much appreciated.
    Thanks,
    Frank

    You can't be sure a read() will read in all the data from a client in one call.
    For example, say your message from the client to the server is of the following format. <start>message here<end>, where <start> indicates the start of a message and <end> the end of the message. In one read() call you might get "<start>message he". Your server would recognize this is partially correct but it needs the rest of the message. The server would store this and on the second read() you might get "re<end>" for the complete message.
    The purpose of non-blocking I/O is so you don't have to wait around for the second part of the message, you can process other client messages while the first client finishes sending their message. This way other clients aren't waiting around while you(the server) sit and wait for client 1 to finish sending it's data.
    So basically there is no gaurantee you will get a whole message intact. Your protocol will have to deal with partial messages, recognize them, store the partial message in a buffer, and on subsequent reads get the rest of the message.
    Nick

  • [svn:bz-trunk] 12951: Changed synchronized PropertyProxyRegistry#getRegistry method to non-synchronized to avoid threads blocking in message push .

    Revision: 12951
    Revision: 12951
    Author:   [email protected]
    Date:     2009-12-15 02:17:31 -0800 (Tue, 15 Dec 2009)
    Log Message:
    Changed synchronized PropertyProxyRegistry#getRegistry method to non-synchronized to avoid threads blocking in message push.
    Checkintests: Pass with the usual 3-4 tests that time out with and without this change.
    QA: Yes
    Doc: No
    Modified Paths:
        blazeds/trunk/modules/core/src/flex/messaging/io/PropertyProxyRegistry.java

    Revision: 12951
    Revision: 12951
    Author:   [email protected]
    Date:     2009-12-15 02:17:31 -0800 (Tue, 15 Dec 2009)
    Log Message:
    Changed synchronized PropertyProxyRegistry#getRegistry method to non-synchronized to avoid threads blocking in message push.
    Checkintests: Pass with the usual 3-4 tests that time out with and without this change.
    QA: Yes
    Doc: No
    Modified Paths:
        blazeds/trunk/modules/core/src/flex/messaging/io/PropertyProxyRegistry.java

  • Thread vs Non-Blocking - invoke thead

    Hi,
    My question related to Thread vs Non-Blocking IO used for network application. If my application needs to handle several thousands or even ten thousand connection simultaneously, did I little research, I concluded that instead of having 10,000 thread running (don't know even that number is possible), I should use NIO instead. My question is that, if I use NIO and fire up a thread everytime I had new data coming in to process, will over head of creating new thread reduce performance a lot than having all the thread running all the time? Should I handle incoming data sequentially and try to avoid blocking during the process?
    TIA

    If you would take the trouble of reading the previous 10 or 20 posts in this forum about threads and/or NIO you would have your answer, or at least most of it.

  • Non-blocking file selector?

    Running W98/Labview 5.1.1, I have a DAQ application that collects data and
    streams it to file. For this I would like to be able to change output
    files without breaking the DAQ loop. For some reason, however the DAQ loop
    occurence will time out the moment I open the file dialog, even though
    the dialog runs in it's own while loop and even in it's own sub VI with
    low priority. Any suggestions how I could get a non-blocking dialog box?
    TIA,
    Rudolf

    Hi Rudolf,
    take a look
    http://zone.ni.com/devzone/devzoneweb.nsf/opendoc?openagent&75C636329327A87B862568690074800A&cat=8ABEC12D4C0AA4A3862567AC00583899
    I hope it help you in many cases.
    Mike
    Rudolf Potucek wrote:
    > Running W98/Labview 5.1.1, I have a DAQ application that collects data and
    > streams it to file. For this I would like to be able to change output
    > files without breaking the DAQ loop. For some reason, however the DAQ loop
    > occurence will time out the moment I open the file dialog, even though
    > the dialog runs in it's own while loop and even in it's own sub VI with
    > low priority. Any suggestions how I could get a non-blocking dialog box?
    >
    > TIA,
    >
    > Rudolf

  • Are the experts wrong about non-blocking SocketChannels?

    Everyone says to use the new SocketChannel and Selector for "highly scalable" server applications. So I ran a couple of tests using non-blocking (via Selector) and thread-per-connection SocketChannels.
    The Selector version consumes 8x more cpu than the thread-per-connecton version!
    Using JDK 1.4.1 FCS on Win2K, with 1000 socket connections each sending 1k bytes per second, the Selector version was consuming 40% cpu with 10 threads; the thread-per-connection version (using blocking SocketChannels) was only consuming about 5% cpu with 1009 threads.
    So, are the experts wrong? Is there a performance problem when number of SocketChannels exceed a certain threshold?
    For anyone interested, here's the source code:
    Non-Blocking Server using Selector
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    import java.nio.charset.CharsetEncoder;
    import java.nio.channels.FileChannel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Set;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    public class Server4 implements Runnable
    private static int port = 80;
    public static void main(String args[]) throws Exception
    Server4 server = new Server4();
    Thread thread = new Thread(server);
    thread.setDaemon(true);
    thread.start();
    thread.join();
    public Server4() throws IOException
    ServerSocketChannel server = ServerSocketChannel.open();
    InetSocketAddress isa = new InetSocketAddress(port);
    server.configureBlocking(false);
    server.socket().bind(isa);
    m_selector = Selector.open();
    server.register(m_selector, SelectionKey.OP_ACCEPT);
    Charset utf8 = Charset.forName("UTF-8");
    m_decoder = utf8.newDecoder();
    m_encoder = utf8.newEncoder();
    public void run()
    int count = 0;
    try
    ByteBuffer buffer = ByteBuffer.allocateDirect(2048);
    //FileOutputStream fos = new FileOutputStream("server4.dat");
    //FileChannel fc = fos.getChannel();
    while (m_selector.select() > 0)
    Set keys = m_selector.selectedKeys();
    for (Iterator itr = keys.iterator(); itr.hasNext(); )
    SelectionKey key = (SelectionKey) itr.next();
    itr.remove();
    if (key.isAcceptable())
    System.out.println("accept: " + (++count));
    ServerSocketChannel server
    = (ServerSocketChannel) key.channel();
    SocketChannel channel = server.accept();
    channel.configureBlocking(false);
    channel.register(m_selector, SelectionKey.OP_READ);
    else
    SocketChannel channel = null;
    try
    if (key.isReadable())
    channel = (SocketChannel) key.channel();
    int bytes = channel.read(buffer);
    if (bytes <= 0) // Linux does not throw IOException
    channel.close(); // will also cancel key
    System.out.println("connection closed " + count);
    else
    buffer.flip();
    //fc.write(buffer);
    buffer.clear();
    catch (IOException ioe) // connection closed by client
    System.out.println("readable: " + ioe.getMessage());
    sm_logger.log(Level.INFO, ioe.getMessage(), ioe);
    Throwable cause = ioe.getCause();
    if (cause != null)
    System.out.println("cause: "
    + cause.getClass().getName()
    + ": " + cause.getMessage());
    channel.close(); // will also cancel key
    --count;
    catch (IOException e)
    System.out.println("run: " + e.getMessage());
    sm_logger.log(Level.SEVERE, e.getMessage(), e);
    catch (Exception e)
    System.out.println("run: " + e.getMessage());
    sm_logger.log(Level.SEVERE, e.getMessage(), e);
    private Selector m_selector;
    private CharsetDecoder m_decoder;
    private CharsetEncoder m_encoder;
    private static Logger sm_logger = Logger.getLogger("Server");
    Thread-Per-Connection Server
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.ByteBuffer;
    import java.nio.CharBuffer;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    import java.nio.charset.CharsetEncoder;
    import java.nio.channels.FileChannel;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Set;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    public class MultiThreadServer implements Runnable
    private static int port = 80;
    public static void main(String[] args) throws Exception
    ServerSocketChannel server = ServerSocketChannel.open();
    InetSocketAddress isa = new InetSocketAddress(port);
    server.socket().bind(isa);
    int count = 0;
    while (true)
    SocketChannel channel = server.accept();
    System.out.println("accept: " + (++count));
    MultiThreadServer worker = new MultiThreadServer(channel);
    Thread thread = new Thread(worker);
    thread.setDaemon(true);
    thread.start();
    public MultiThreadServer(SocketChannel channel) throws IOException
    m_channel = channel;
    public void run()
    ByteBuffer buffer = ByteBuffer.allocateDirect(2048);
    int bytes = 0;
    try
    while ((bytes = m_channel.read(buffer)) > 0)
    buffer.flip();
    // process buffer
    buffer.clear();
    System.out.println("connection closed");
    m_channel.close();
    catch (IOException e)
    System.out.println("run: " + e.getMessage());
    sm_logger.log(Level.SEVERE, e.getMessage(), e);
    catch (Exception e)
    System.out.println("run: " + e.getMessage());
    sm_logger.log(Level.SEVERE, e.getMessage(), e);
    private SocketChannel m_channel;
    private static Logger sm_logger = Logger.getLogger("MultiThreadServer");
    Client
    import java.io.*;
    import java.net.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.charset.*;
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.Set;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    public class MultiClient implements Runnable
    public static void main(String[] args) throws Exception
    if (args.length < 1)
    System.out.println("usage: java MultiClient number [host]");
    System.exit(1);
    int number = Integer.parseInt(args[0]);
    String host = (args.length == 2) ? args[1] : "localhost" ;
    Thread[] threads = new Thread [number];
    InetSocketAddress address = new InetSocketAddress(host, 80);
    for (int i = 0; i < number; i++)
    MultiClient client = new MultiClient(address, Integer.toString(i));
    threads[i] = new Thread(client);
    threads.setDaemon(true);
    for (int i = 0; i < number; i++)
    threads[i].start();
    for (int i = 0; i < number; i++)
    threads[i].join();
    public MultiClient(InetSocketAddress address, String id)
    throws InterruptedException, IOException
    m_id = id;
    Charset charset = Charset.forName("UTF-8");
    m_decoder = charset.newDecoder();
    m_encoder = charset.newEncoder();
    m_channel = SocketChannel.open();
    m_channel.connect(address);
    if (id.equals("0"))
    Socket socket = m_channel.socket();
    System.out.println("SO_SNDBUF=" + socket.getSendBufferSize()
    + ",SO_TIMEOUT=" + socket.getSoTimeout()
    + ",SO_KEEPALIVE=" + socket.getKeepAlive());
    byte[] buf = new byte [1024]; // bufsize = 1K
    Arrays.fill(buf, (byte) m_id.charAt(0));
    m_buffer = ByteBuffer.allocateDirect(1024);
    m_buffer.put(buf);
    m_buffer.flip();
    Thread.currentThread().sleep(50L);
    public void run()
    System.out.print(m_id);
    try
    while (true)
    m_channel.write(m_buffer);
    m_buffer.rewind();
    Thread.currentThread().sleep(1000L);
    catch (IOException ioe)
    ioe.printStackTrace();
    catch (InterruptedException ie)
    System.err.println(ie.toString());
    private String m_id;
    private CharsetEncoder m_encoder;
    private CharsetDecoder m_decoder;
    private SocketChannel m_channel;
    private ByteBuffer m_buffer;

    {This is a crosspost. I posted this earlier today at http://forum.java.sun.com/thread.jsp?forum=4&thread=319822 before I stumbled on a search phrase that located this older thread.
    All follow-ups should be on haam's thread instead of mine. The important point below is that NIO select() behavior (vs. threading IO)  is [b]worse under Windows but better under Solaris. This seems fundamentally broken. }
    My company sells a scalable multi-user server platform built on Java 2.
    It runs under Java 1.3.1 (and 1.4.0 windows) using multiple threads for communications, and 1.4.x (unix) using NIO. We were happy to see that 1.4.1 (windows) fixed the problem drastically limiting the number of selectable ports. :-)
    The bad news is that whatever the VM is doing "under the sheets" to fix the problem seems to perform very poorly in terms of CPU:
    I compared connecting 500 simulated users to a Solaris 8 and a Win2K box. These users were in 25 chat rooms, each sending a chat message every 30 seconds. (There was plenty of memory on each machine. There was no swapping in either case. Clock/CPU type doesn't matter as this isn't about comparing a machine to a machine, but different load characteristics -within- a machine environment.)
                    Threaded IO      NIO/Select
    Solaris 1.4.1     20-30%           15- 20%
    Windows 1.4.1     40-50%           95-100%Numbers are % of CPU as reported by 'top' and the Win2K task manager.
    Both platforms showed the expected significant improvement in memory usage when moving from standard threaded IO to NIO.
    Strangely, the Windows implementation of the VM showed a significant (and unexpected) degradation of NIO performance vs. the threaded model, whereas the Solaris VM behaved as expected: NIO outperformed threaded IO.
    Our best guess is that the Selector fix in 1.4.1 is implemented in some cpu-intensive way; perhaps polling. As a result, we still can't use NIO for Wintel boxes running our server. :-( To us, Selector
    is still broken.
    Has anyone else seen results like this? Have we missed some configuration parameter that will fix this?
    I thought the big upside of using select() was supposed to be performance. :-P
    F. Randall Farmer
    State Software, Inc.
    http://www.statesoftware.com

  • Non-blocking SocketChannels

    I'm trying to learn how to use non-blocking socket channles, but I haven't found much info (nor luck) so far.
    To learn, I'm building a server and a client. The server accepts input from the clients and process it in only one thread. The clients should send Objects to the server, and the server process them and return the result also as an Object. For this, I'm trying to use ObjectOutputStream and ObjectInputStream.
    The problem I don't know how to solve is that the SocketChannel is in non-bolcking mode, so I can't use their input/output streams (I get a IllegalBlockingModeException). In the server process loop I can reconfigure the SocketChannel to blocking mode to be able to read the Object, but I can't configure it to non-blocking mode again because I get a CancelledKeyException.
    Does anyone know how to work with InputStreams and non-blocking channels? Or where to find more info about it?
    Here are the relevant part of the server code:
    Set ready = selector.selectedKeys();
    Iterator i = ready.iterator();
    while (i.hasNext()) {
       try {
          SelectionKey sk = i.next();
          i.remove();
          if (sk.isAcceptable()) {
             ServerSocketChannel ssc = (ServerSocketChannel)sk.channel();
             SocketChannel sc = ssc.accept();
             sc.configureBlocking(false);
             sc.register(selector, SelectionKey.OP_READ);
          } else if (sk.isReadable()) {
             SocketChannel sc = (SocketChannel)sk.channel();
             // PROBLEM: If the channel is in non-blocking mode
             // I cannot use InputStreams
             sk.cancel();
             sc.configureBlocking(true);
             // Read the object sent by the client
             ObjectInputStream in = new ObjectInputStream(Channels.newInputStream(sc));
             Object o = in.readObject();
             // PROBLEM: Can't put the channel back to non-blocking mode
             sc.configureBlocking(false);
             sc.register(selector, SelectionKey.OP_READ); // CancelledKeyException
       } catch (...){
    }

    In my client, this is working fine:
    ObjectOutputStream oos = null;
    ObjectInputStream ois = null;
    for (int i = 0; i < 30000; i++) {
       oos = new ObjectOutputStream(sc.socket().getOutputStream());
       oos.writeObject(object);
       oos.flush();
       ois = new ObjectInputStream(sc.socket().getInputStream());
       Object o = ois.readObject();
    }But trying to do it like this throws a StreamCorruptedException at the server side.
    ObjectOutputStream oos = new ObjectOutputStream(sc.socket().getOutputStream());
    ObjectInputStream ois = new ObjectInputStream(sc.socket().getInputStream());
    for (int i = 0; i < 30000; i++) {
       oos.writeObject(object);
       oos.flush();
       Object o = ois.readObject();
    }Do you know why?

  • Non-blocking connection on a SocketChannel?

    I'm trying out the non-blocking connection of a SocketChannel. So I wrote the following test code and supply a list of IPs (both good and bad IPs). But disregard the IPs I always get the result of a channel being in connection pending state (even for some bogus IPs). Any help will be great.
    public class ConnectTest
        public static void main(String[] args) throws
    Exception
            List<SocketChannel> channels = new ArrayList<SocketChannel>();
            for ( String s: args )
                SocketChannel channel = SocketChannel.open();
                channel.configureBlocking(false);
                channels.add(channel);        
                InetSocketAddress remote = new InetSocketAddress(s, 80);
                channel.connect(remote);
            System.out.println("wait for timeout...");
            Thread.sleep(10000);
            for ( SocketChannel c : channels )
                if ( c.isConnected() )
                    System.out.println(c.socket().getInetAddress() + " connected ");
                else if ( c.isConnectionPending() )
                    System.out.println(c.socket().getInetAddress() + " connection pending ");               
                else
                    System.out.println(c.socket().getInetAddress() + " timeout ");
                c.close();
    }

    Forget the sleep: use a Selector, selecting on OP_CONNECT. When you get it, call SocketChannel.finishConnect() for the channel(s) selected. If that method returns 'true', the connection is complete. If it returns 'false', the connection is still pending (and in fact OP_CONNECT should not have fired); if it throws an exception, the connection attempt has failed.
    If the connection is complete you must also deregister it for OP_CONNECT before registering it for OP_READ or OP_WRITE.

  • Non-blocking socket concurrent limitation?

    I have 2 socket program,one is server side used nio package with JDK1.4.1,the other is client used traditional socket,the client will initialize about 50
    threads trying to connect with server when starting,but only about 15
    can be accepted,these 2 program are runnning in the same computer which
    OS is win2000 professional PC.
    the followd is these code:
    please make a probe with them ,and tell me what's going on?
    server:
    package nio_select_demo;
    import java.io.*;
    import java.net.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.util.*;
    import java.nio.charset.Charset;
    import java.nio.charset.CharsetDecoder;
    public class Server implements Runnable
    // The port we will listen on
    private int port;
    // A pre-allocated buffer for processing data
    private final ByteBuffer buffer = ByteBuffer.allocate( 16384 );
    private ByteBuffer resBuf = ByteBuffer.allocate( 128 );
    Selector selector;
    AddInfo test ;
    public Server( int port ) {
    this.port = port;
    // for (int i=0; i<threadnum; ++i) {
    new Thread( this ).start();
    test = new AddInfo();
    test.start();
    public void run() {
    try {
    // create a ServerSocketChannel
    ServerSocketChannel ssc1 = ServerSocketChannel.open();
    // ServerSocketChannel ssc2 = ServerSocketChannel.open();
    // Set it to non-blocking
    ssc1.configureBlocking( false );
    // Get the Socket connected to this channel, and bind it
    // to the listening port
    ServerSocket ss = ssc1.socket();
    InetSocketAddress isa = new InetSocketAddress( port );
    ss.bind( isa , 60 );
    // Create a new Selector for selecting
    selector = Selector.open();
    // Register the ServerSocketChannel, so we can
    // listen for incoming connections
    ssc1.register( selector, SelectionKey.OP_ACCEPT );
    System.out.println( "Listening on port "+port );
    int n = 0;
    while (true) {
    // See if we've had any activity -- either
    // an incoming connection, or incoming data on an
    // existing connection
    int num = selector.select();
    // If we don't have any activity, loop around and wait
    // again
    if (num == 0) {
    continue;
    // Get the keys corresponding to the activity
    // that has been detected, and process them
    // one by one
    Set keys = selector.selectedKeys();
    Iterator it = keys.iterator();
    while (it.hasNext()) {
    // Get a key representing one of bits of I/O
    // activity
    SelectionKey key = (SelectionKey)it.next();
    // What kind of activity is it?
    if ((key.readyOps() & SelectionKey.OP_ACCEPT) ==
    SelectionKey.OP_ACCEPT) {
    System.out.println( "accept request" );
    // It's an incoming connection.
    // Register this socket with the Selector
    // so we can listen for input on it
    SocketChannel sc = ((ServerSocketChannel)key.channel()).accept();
    System.out.println( "Got connection from "+sc.socket());
    // Make sure to make it non-blocking, so we can
    // use a selector on it.
    //SocketChannel sc = s.getChannel();
    sc.configureBlocking( false );
    // Register it with the selector, for reading
    sc.register( selector, SelectionKey.OP_READ| SelectionKey.OP_WRITE);
    } else if ((key.readyOps() & SelectionKey.OP_READ) ==
    SelectionKey.OP_READ) {
    //ssc.register(selector , SelectionKey.OP_READ);
    SocketChannel sc = null;
    try {
    // It's incoming data on a connection, so
    // process it
    sc = (SocketChannel)key.channel();
    Socket s1 = sc.socket();
    s1.setTcpNoDelay(true);
    System.out.println( "enter processing data" );
    boolean ok = processInput( key );
    synchronized (selector) {
    key.interestOps(key.interestOps() & ~SelectionKey.OP_READ);
    // If the connection is dead, then remove it
    // from the selector and close it
    if (!ok) {
    key.cancel();
    System.out.println("dead");
    Socket s = null;
    try {
    s = sc.socket();
    s.close();
    } catch( IOException ie ) {
    System.err.println( "Error closing socket "+s+": "+ie );
    } catch( IOException ie ) {
    ie.printStackTrace();
    // On exception, remove this channel from the selector
    key.cancel();
    System.err.println( "Error raised in this socket");
    try {
    sc.close();
    } catch( IOException ie2 ) { System.out.println( ie2 ); }
    System.out.println( "Closed "+sc );
    else if ((key.readyOps() & SelectionKey.OP_WRITE) ==
    SelectionKey.OP_WRITE) {
    System.out.println("Enter Writing");
    String response = new String();
    if((response=this.test.getInfo())!=null){
    resBuf.clear();
    SocketChannel sc = (SocketChannel)key.channel();
    resBuf = ByteBuffer.wrap( response.getBytes("ISO-8859-1" ) );
    sc.write( resBuf );
    synchronized (selector) {
    key.interestOps(key.interestOps() & ~SelectionKey.OP_WRITE);
    // We remove the selected keys, because we've dealt
    // with them.
    keys.clear();
    } catch( IOException ie ) {
    System.err.println( ie );
    private boolean processInput( SelectionKey key ) throws IOException {
    buffer.clear();
    SocketChannel sc = (SocketChannel)key.channel();
    sc.read( buffer );
    buffer.flip();
    String response = new String("response ok");
    // If no data, close the connection
    if (buffer.limit()==0) {
    return false;
    Charset charset=Charset.forName("ISO-8859-1");
    CharsetDecoder decoder = charset.newDecoder();
    CharBuffer charBuffer = decoder.decode(buffer);
    System.out.println(charBuffer.toString());
    System.out.println( "Processed "+buffer.limit()+" from "+sc );
    return true;
    static public void main( String args[] ) throws Exception {
    int port = Integer.parseInt( args[0] );
    System.out.println(port);
    new Server( port );
    cilent:
    import java.io.*;
    import java.net.*;
    import java.util.*;
    public class Client implements Runnable
    private String host;
    private int port;
    private int acport;
    //the size of buffer on how much we write and read per cycle
    private static final int maxWriteSize = 128;
    public Client( String host, int port, int numThreads ) {
    this.host = host;
    this.port = port;
    for(int i =0;i<50;i++){//initialize 50 client threads
    new Thread(this).start();
    public void run() {
    byte buffer[] = new byte[maxWriteSize];
    byte buffer2[] = new byte[maxWriteSize];
    try {
    Socket s = new Socket( );
    InetSocketAddress sa = new InetSocketAddress(host,this.port);
    s.connect(sa);
    System.out.println(s);
    s.setTcpNoDelay(true);
    InputStream in = s.getInputStream();
    OutputStream out = s.getOutputStream();
    for (int i=0; i<maxWriteSize; ++i) {
    buffer[i] = (byte)'a';
    out.write( buffer, 0, maxWriteSize );
    int pause = 500;
    in.read( buffer , 0 , maxWriteSize );
    System.out.println( Thread.currentThread()+" wrote "+maxWriteSize);
    String res = new String ( buffer );
    String res2 = new String ( buffer2 );
    System.out.println( res );
    try { Thread.sleep( pause ); } catch( InterruptedException ie ) {}
    } catch( Exception ie ) {
    ie.printStackTrace();
    System.err.println(ie.getMessage());
    static public void main( String args[] ) throws Exception {
    String host = "127.0.0.1";
    int port = Integer.parseInt( args[0] );
    int numThreads = Integer.parseInt( args[1] );
    new Client( host, port, numThreads );

    I have found the reason!!!
    because of system resource limitation,windows can't afford to maintain
    so many concurrent stream-IO,so some socket will be closed.
    I modified the client side code,adding thes segments to client instantialize
    such as :
    public Client( String host, int port, int numThreads ) {
    for(int i =0;i<1000;i++){
    new Thread(this).start();
    try {
    Thread.currentThread().sleep(100);//give system some idle
    } catch (InterruptedException e) {
    /* ignore */
    then the server can accept more than 1000 client request concurrently.

  • Non-Blocking I/O Implementation Issue

    Hi All,
    I am trying out the latest JDK 1.4 java.nio.* package. I modified the NBTimeServer and wrote a client which connects to the NBTimeServer and tries to pass messages to and fro. I always succeed to pass on roundtrip of msgs and then Server blocks my client forever. I have modified NBTimeServer to accomodate one client only. Any help or comments on this would be really appreciated. Code is below. Feel free to try it out if want to see what I am trying to convey in this message.
    /*******Server Code*******/
    Modified this code to test mulitple to and fro msgs between client and server.
    Only one client will ever be able to connect to this server during life of a server.
    My point here is to demonstrate the to and fro comm between one client and one server
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    import java.net.*;
    import java.util.*;
    import java.nio.charset.*;
    import java.util.regex.*;
    // Listen on a port for connections and write back the current time.
    public class NBTimeServer {
    private static final int DEFAULT_TIME_PORT = 8900;
    // Constructor with no arguments creates a time server on default port.
    public NBTimeServer() throws Exception {
         acceptConnections(this.DEFAULT_TIME_PORT);
    // Constructor with port argument creates a time server on specified port.
    public NBTimeServer(int port) throws Exception {
         acceptConnections(port);
    // Accept connections for current time. Lazy Exception thrown.
    private static void acceptConnections(int port) throws Exception {
         // Selector for incoming time requests
         Selector acceptSelector = SelectorProvider.provider().openSelector();
         Selector rwSelector = SelectorProvider.provider().openSelector();
         // Create a new server socket and set to non blocking mode
         ServerSocketChannel ssc = ServerSocketChannel.open();
         ssc.configureBlocking(false);
         // Bind the server socket to the local host and port
         InetAddress lh = InetAddress.getLocalHost();
         InetSocketAddress isa = new InetSocketAddress(lh, port);
         ssc.socket().bind(isa);
         // Register accepts on the server socket with the selector. This
         // step tells the selector that the socket wants to be put on the
         // ready list when accept operations occur, so allowing multiplexed
         // non-blocking I/O to take place.
         SelectionKey acceptKey = ssc.register(acceptSelector,
                             SelectionKey.OP_ACCEPT);
         int keysAdded = 0;
         // Here's where everything happens. The select method will
         // return when any operations registered above have occurred, the
         // thread has been interrupted, etc.
         while ((keysAdded = acceptSelector.select()) > 0) {
         // Someone is ready for I/O, get the ready keys
         Set readyKeys = acceptSelector.selectedKeys();
         Iterator i = readyKeys.iterator();
         // Walk through the ready keys collection and process date requests.
         while (i.hasNext()) {
              SelectionKey sk = (SelectionKey)i.next();
              i.remove();
              // The key indexes into the selector so you
              // can retrieve the socket that's ready for I/O
              ServerSocketChannel nextReady =
              (ServerSocketChannel)sk.channel();
              // Accept the date request and send back the date string
              Socket s = nextReady.accept();
                        SocketChannel sc = s.getChannel();
    System.out.println("Got client channel..");
              sc.configureBlocking(false);
              SelectionKey readKey = sc.register(rwSelector,
                             SelectionKey.OP_READ|SelectionKey.OP_WRITE);                     
              int count = 0;
    while(true) {
    if((count = rwSelector.select(1000L)) > 0) {
    Set readKeys = rwSelector.selectedKeys();
    Iterator i1 = readKeys.iterator();
    while(i1.hasNext()) {
    System.out.println("Loop in Iterator");
    SelectionKey sk1 = (SelectionKey)i1.next();
    i1.remove();
    if(sk1.isReadable()) {
    DataInputStream sin = new DataInputStream(new BufferedInputStream(s.getInputStream(), 4096));
    System.out.println(sin.readInt());
    if(sk1.isWritable()) {
    DataOutputStream sout = new DataOutputStream(new BufferedOutputStream(s.getOutputStream(), 4096));
    PrintWriter out = new PrintWriter(sout, true);
              Date now = new Date();
              out.println(now);
    // Entry point.
    public static void main(String[] args) {
         // Parse command line arguments and
         // create a new time server (no arguments yet)
         try {
              NBTimeServer nbt = new NBTimeServer();
         } catch(Exception e) {
              e.printStackTrace();          
    /******End Server Code********/
    /*****Begin Client Code********/
    import java.io.*;
    import java.net.*;
    import java.util.*;
    // Listen on a port for connections and write back the current time.
    public class NBTimeClient {
    private static final int DEFAULT_TIME_PORT = 8900;
    public static void main(String args[]) throws Exception {
    InetAddress lh = InetAddress.getLocalHost();
    Socket s = new Socket(lh, DEFAULT_TIME_PORT);
    DataInputStream din = new DataInputStream(new BufferedInputStream(s.getInputStream(), 4096));
    DataOutputStream dout = new DataOutputStream(new BufferedOutputStream(s.getOutputStream(), 4096));
    //Read the time
    System.out.println(din.readLine());
    //send some junk which is read by server
    dout.writeInt(1299);
    dout.flush();
    //read time again -- I never get anything here and I am blocked here...
    System.out.println(din.readLine());
    //send some junk back to the server
    dout.writeInt(1299);
    dout.flush();
    s.close();
    /*******End Client Code**********/
    thanks,
    Xtrimity

    The reason it blocks forever is that you need to keep reusing your main select. That is where the non-blocking event will come from. Here is a bit of code that doesn't block forever.
    Tim
    http://tim.owlmountain.com
    import java.io.*;
    import java.nio.*;
    import java.nio.channels.*;
    import java.nio.channels.spi.*;
    import java.net.*;
    import java.util.*;
    import org.apache.log4j.*;
    public class NBServer3 {
    int _port = 4000;
    Selector _selector = null;
    ServerSocketChannel _selectableChannel = null;
    int _keysAdded = 0;
    static Category log =
    Category.getInstance(NBServer3.class.getName());
    static String QUIT_SERVER = "quit";
    public NBServer3() {
    public NBServer3( int port ) {
    this._port = port;
    public void initialize()
    throws IOException {
    this._selector = SelectorProvider.provider().openSelector();
    this._selectableChannel = ServerSocketChannel.open();
         this._selectableChannel.configureBlocking(false);
         InetAddress lh = InetAddress.getLocalHost();
         InetSocketAddress isa = new InetSocketAddress(lh, this._port );
         this._selectableChannel.socket().bind(isa);
    public void finalize()
    throws IOException {
    this._selectableChannel.close();
    this._selector.close();
    public void acceptConnections()
    throws IOException {
    Selects a set of keys whose corresponding channels are ready for I/O
    operations. This method performs a non-blocking selection operation.
    If no channels have become selectable since the previous selection
    operation then this method immediately returns zero.
    Returns:
    The number of keys, possibly zero, whose ready-operation sets
    were updated by the selection operation
    do {
    SelectionKey acceptKey =
    this._selectableChannel.register( this._selector,
    SelectionKey.OP_ACCEPT );
    log.debug( "Acceptor loop..." );
    while (( this._keysAdded = acceptKey.selector().select()) > 0 ) {
    log.debug( "Selector returned "
    + this._keysAdded + " ready for IO operations" );
    Set readyKeys = this._selector.selectedKeys();
    Iterator i = readyKeys.iterator();
    while (i.hasNext()) {
    SelectionKey key = (SelectionKey)i.next();
    i.remove();
    if ( key.isAcceptable() ) {
    ServerSocketChannel nextReady =
    (ServerSocketChannel)key.channel();
    log.debug( "Processing selection key read="
    + key.isReadable() + " write=" + key.isWritable() +
    " accept=" + key.isAcceptable() );
    Socket s = nextReady.accept();
    s.getChannel().configureBlocking( false );
    SelectionKey readKey =
    s.getChannel().register( this._selector,
    SelectionKey.OP_READ );
    readKey.attach( s );
    else if ( key.isReadable() ) {
    SelectableChannel nextReady =
    (SelectableChannel) key.channel();
    log.debug( "Processing selection key read="
    + key.isReadable() + " write=" + key.isWritable() +
    " accept=" + key.isAcceptable() );
    Socket socket = (Socket) key.attachment();
    BufferedReader in = new BufferedReader(
    new InputStreamReader( socket.getInputStream() ));
    String line = null;
    if ( (line = in.readLine() ) != null )
    log.debug( line );
    log.debug( "End acceptor loop..." );
    } while ( false ); //FIXIT tim this should be false. justa test
    public static void main( String[] args ) {
    BasicConfigurator.configure();
    NBServer3 nbServer = new NBServer3();
    try {
    nbServer.initialize();
    } catch ( IOException e ) {
    e.printStackTrace();
    System.exit( -1 );
    try {
    nbServer.acceptConnections();
    catch ( IOException e ) {
    e.printStackTrace();
    log.error( e );

  • SO timeout relevance in non-blocking NIO ServerSocketChannel

    I converted a threaded blocking server from using the standard blocking IO with a thread for each connection to using non-blocking NIO channels. Works great but I'm trying to understand the SO timeout relevance in the context of non-blocking NIO channels. Is there any relevance and should I set an SO timeout on the ServerSocket associated with a ServerSocketChannel and if so how should I handle it?

    No. Socket timeouts are for blocking mode. If you need timeouts in non-blocking mode you have to do them yourself, taking advantage of the Selector.select(long timeout) method and keeping track of activity times per channel yourself. You should use that select() method anyway, rather than just blocking indefinitely, as it gives you a chance to catch up on housekeeping, dead channels, etc. For example as a very naive approach if nothing happens in say a select timeout of 10 minutes you might want to close all accepted SocketChannels.

  • What is non blocking IO?

    I have heard that 1.4 supports non blocking IO, and that this is greath for servers. What is it, how does it work and why is it so good?

    I could be wrong - but if they have not yet done so
    a good optimization would be to rearrange the
    select list - such that the sockets that have
    an event appears at the top of the list.
    This way - when the select completes - it tells
    you that there are - say 2 - active events - you
    would then just read the first two channels on
    the select list.From the API javadoc:
    The selected-key set is the set of keys such that each key's channel was detected to be ready for at least one of the operations identified in the key's interest set during a prior selection operation. This set is returned by the selectedKeys method. The selected-key set is always a subset of the key set.
    ie- select and iterate. No polling involved.
    They just completed the java EventListener model
    for the GUI. It would have been simple and clean
    to implement a similar model for io. You have
    the io channel - you would just attach an event
    listener to it much like you would do for a control.
    When an io finishes on a channel, you would be
    told immediately the channel that the io completed
    and what event occured - read, write etc.
    Now you could have a million sockets
    ( if ever unix could support that many file
    discriptors )
    and you when an io completes no need to poll
    a bunch of idle sockets.Question: What thread would this run in?
    * Does it run in the network layer? How many concurrent event notifications can the network layer at any one time? Is it likely it would be an EventQueue-esque single thread?
    * Does it spawn a new thread for each event? This would certainly yield worse results than spawning a new thread for each socket, since each socket would generate a vast number of events.
    * Does it have a thread pool to deal with the events? Then you would be using exactly the same model as java.nio's Selector.
    FYI: The windows NT asynchronous IO model uses
    an event model - IO completion ports. It is far more
    modern, advanced and efficient that the select / poll
    model used in unix.Do you have any links for more information?
    Sun could have incorporated the most modern / best
    features into java and make it competitive. Instead
    they went for least common denominator.Sun's nio package was (somewhat) based on a community project, and was integrated into Java on JSR-051
    http://www.cs.berkeley.edu/~mdw/proj/java-nbio/
    If there were such an initiative for NT-style asynchronous IO, and this was proven to be more efficient, then I imagine it will be much more likely to be integrated with the language.
    If it isn't, you could still use the community-based implementation, as you could with the nbio package before 1.4 was released.
    Just because Sun doesn't do something, doesn't mean you can't!

  • Both blocking and non-blocking io

    I'm wondering if this scenario is possible with the new nio classes:
    I have a caching server. Clients connect to the server and occasionally send requests for objects. I'd like to use the nio non-blocking APIs to detect that there is a read pending on a socket. However, once I detect this, I'd like to go into a blocking loop to process the request. After this done, I'd like to go back into non-blocking mode and wait for another request.
    It seems like this should be possible but the (woefully lacking) documentation isn't clear. Neither is the source code, apparently.
    I've got a test case working but I was hoping someone could validate for me that this is support behavior. It's done by waiting for the isReadable() key then calling socket.keyFor(selector).cancel(); and then socket.configureBlocking(true); The reads are then done in blocking mode until the request is done and then the socket is registered with the selector again.
    Thanks for any help on this.

    I have to ask why you would want to mix blocking and non-blocking I/O.
    The only reason you would (IMHO) want to use non-blocking I/O is in a highly concurrent system, to increase the maximum load a system can handle.
    The main reason you would want to use blocking I/O rather than non-blocking I/O would be to minimise the latency for a single request.
    Unfortunately, the two don't seem to mix together very well... by switching a thread to blocking, you decrease the latency for a single request, but increase latency for the other requests due to reduced resources available. Similarly, by switching to blocking, you are requiring a dedicated thread for that request, so limiting the number of concurrent requests that can be serviced.
    That is, it seems to me that using both blocking and non-blocking I/O introduces the weaknesses of both into the system, without gaining much of the benefits of either.
    The above aside, the method you gave looks like it would work as you expect, depending on what you are doing with thread creation/delegation. Did your test case work as expected?

  • Writing Java Non-Blocking Socket Server for  Winsock Client

    Hi.
    Im a newbie to Sockets. I need to write a Non-Blocking Socket server (using java.nio) that accepts connection and reads the data sent by WinSock clients, and write them to another winsock client. Its quite intriguing. How do I do that? Is it possible?
    Thanks in advance
    Arun

    Well, in traditional 4.2 BSD sockets, you'd fill up a set of filedescriptors of connections (an array of bits usually), and push that in the read parameter of a call to 'select'. Select then blocks until at least one of the file descriptors become available for reading, or writing if you also made an fd_set full of file descriptors (but you can usually write freely to a socket, so there is not much use for that). Then you start finding out which of these file descriptors have actually become available for reading, and you pass those to a bunch of worker-threads. The advantage is that your set of worker-threads can be quite small, while your number of connections can still be quite large (unless, of course, everyone of your clients start talking all at once, but that is no different from the one-socket-one-thread-model that java.net.* forces upon you).
    In java, the 'select' call is replaced by a call to java.nio.channels.Selector.select(); and then the fishing out of the selected stuff comes from java.nio.channels.Selector.selectedKeys().
    To add a thingy to a selector, use (for example) java.nio.channel.ServerSocketChannel.register(Selector, ops, att);
    whereby the ops parameter is the kind of action you'd like to select this channel for; SelectionKey.OP_READ etc..
    The workerthread bit is also easy to write, but I leave that to you as an exercise.

  • Detecting When a Non-Blocking Socket Is Closed by the Remote Host

    Hi,
    Using NIO non blocked sockets how do I detect when a Non-Blocking Socket Is Closed by the Remote Host?
    What I have read is:
    The only way to detect that the remote host has closed the connection is to attempt to read or write from the connection. If the remote host properly closed the connection, read() will return -1. If the connection was not terminated normally, read() and write() will throw an exception.
    I have written a server test program using NIO and an applet connecting to the server program via sockets.
    When I after a successful connection shuts down the browser following happens: The code below comes in an endless loop though mySelector.select returns 0 every time. (The selector is registered for OP_READ). size = 1.
    while (true) {
    int n = mySelector.select();
    int size = mySelector.keys().size();
    if (n == 0) continue;
    Is this an expected result?
    How do I get to know what client has lost connection?
    My environment:
    W2000
    java 1.4.1 build 1.4.1_01-b01
    Browser used: IE 5.0
    Many thanks for your help on this matter!
    Regards Magnus Wistr�m

    What you're doing looks OK to me.
    I wonder whether your thread is being interrupted by Thread.intterupt() somewhere. Try putting a Thread.interrupted() before the select call.
    Sylvia.

Maybe you are looking for

  • How to create Document total in footer

    Dear all,      Anyone plz tell me the code for document total which is calculated from matrix line total Regards, Guru

  • SIRI not processing requests...Servers Overwhelmed?? iOS7 ver

    Ever since the launch of 5s/5c, about 1/3 of the time when I ask Siri to make a call or provide directions, there is a big delay followed by a message that the request cannot be processed at the present time.  This happens at all times of the day, no

  • Network Stalling

    We're looking at the usual "why is my internet so slow?" problem here. Speed tests show good (+7000kbps down/+800kbps up) and other computers on the LAN don't have any problems. My specifics seem to be an initial stall while connecting to a website.

  • Ios 7 and Apple ID

    Okay my mom recently updated to ios7 on her 4s and is now having problems. For example when trying to download an app it asks for a password like it normally does but when she enters her Apple ID password like she normally does it won't accept it. Al

  • How to create a linear regression line series

    I am relatively new to Flex and I am currently working with charts in the data visualization components. It has been requested that I add a linear trendline (ie, linear regression trend line) to a column chart. From what I can tell, there is no linea