2

Each client is registered as an observer once it connected to the server. When any client did changes, another clients would be notified.

My problem is how could I keep the socket connected?

Can I store all connections like Socket[] and check their InputStream every second?

Scottie
  • 1,021
  • 2
  • 14
  • 22
  • 1
    It might help you [Java Server with Multiclient communication.](http://stackoverflow.com/questions/22287439/java-server-with-multiclient-communication?answertab=votes#tab-top) – Braj May 25 '14 at 13:11
  • I probably know its logic. Each client hold one thread on server, then 1k clients may cause server crash? I'm looking for an one thread solution – Scottie May 25 '14 at 13:20

1 Answers1

0

I don't know if i got your problem right... But I'll give it a shot.

The Problem sems to be, that you have 1 ServerSocket and multiple sockets (one for each client) and now you want to get notified/informed about acitvity on these sockets. so you plan on iterating through the list of sockets?

The keyword is nonblocking I/O. Search for the Keyword "selector" or "multiplexing". I'll try to put up a simple example.

I build a really minimal example. But it is a start. This is the whole

package server;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.util.Iterator;
import java.util.Set;

public class Server {

public Server() throws IOException{
    Selector selector = SelectorProvider.provider().openSelector();
    ServerSocketChannel ssc = ServerSocketChannel.open().bind(new InetSocketAddress(9000));
    ssc.configureBlocking(false);       
    ssc.register(selector, 
              SelectionKey.OP_ACCEPT);  


    while(true) {

      int readyChannels = selector.select();

      if(readyChannels == 0) continue;


      Set<SelectionKey> selectedKeys = selector.selectedKeys();

      Iterator<SelectionKey> keyIterator = selectedKeys.iterator();

      while(keyIterator.hasNext()) {

        SelectionKey key = keyIterator.next();

        if(key.isAcceptable()) {
           System.out.println("acceptable");
           SocketChannel socketChan =  ((ServerSocketChannel)key.channel()).accept();
           socketChan.configureBlocking(false);
            socketChan.register(selector, SelectionKey.OP_READ);

        } else if (key.isConnectable()) {
            // a connection was established with a remote server.

        } else if (key.isReadable()) {
            System.out.println("Processing reading...");

            ByteBuffer buf = ByteBuffer.allocate(1024);
            int readedBytes = ((SocketChannel)key.channel()).read(buf);
            System.out.println("Readed: " + readedBytes);
            buf.flip();

            for(byte b : buf.array()) {
                System.out.print((char) b);
            }

        } else if (key.isWritable()) {
            // a channel is ready for writing
        }

        keyIterator.remove();
      }
    }
}

public static void main(String[] args) throws IOException {
    Server server = new Server();

}

}

I can run this, and connect via netcat on port 9000 to it, and send messages from there. Just ONE Thread, with as many client connections as you like....

I used this ressources/examples

http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html and http://docs.oracle.com/javase/7/docs/technotes/guides/io/example/index.html

Timmeey
  • 363
  • 3
  • 9
  • thanks for your sample, but i cannot figure out how to notify all the connected client from your code... what `selector.selectedKeys()` does? Will the infinite loop overwhelms the server? – Scottie May 25 '14 at 16:15
  • The nested while loop will block at while(keyIterator.hasNext()) so no busy-waiting Of course this is just a small example, which wasn't constructed for writing. But i don't think it is to much of a problem to work it out. selector.selectedKeys() returns a Set of Keys. A Key is kind of a token which represents a Chanel/Socket that is registred for a selector. It's a little complicated. Best would be if you read the examples i used http://tutorials.jenkov.com/java-multithreaded-servers/thread-pooled-server.html and http://docs.oracle.com/javase/7/docs/technotes/guides/io/example/index.html – Timmeey May 25 '14 at 16:23