Java Server - Multiple ports?

Myn picture Myn · Feb 22, 2011 · Viewed 30.7k times · Source

I'm about to program a server but am wondering if what I have in mind is possible. My program will be outputting to multiple clients on multiple ports - each port can be accessed by multiple clients.

Normally I would use a threaded socket server, but in this case I need it working for multiple ports. The usage I have in mind is in a vague pseudocode below:

  • Start server
  • Listen for incoming connections on several ports
  • Identify the port being connected to
    • If port 1, start a thread listening to client and outputting message type x
    • If port 2, start a thread listening to client and outputting message type y

Hopefully that makes some sense and you can see what I'm trying to do. Simply put: listen to selected ports, create a threaded socket connection based on which port is being connected to.

Is this doable at all, or am I going to end up multi-threading threaded socket servers?

Edit: Changed wording to better reflect the question.

Answer

Dunes picture Dunes · Feb 22, 2011

It's not possible to for a single instance of ServerSocket to listen to multiple ports. You can of course have multiple ServerSockets. However, as you already know, ServerSocket.accept blocks.

What you can use instead is a ServerSocketChannel. They're used in a similar way, but do not block.

If there are no pending connections when ServerSocketChannel.accept is called then it simply returns null.

You can use with a Selector which takes a set of channels and blocks until at least one has a pending connection.

I don't remember the specifics on how to use them, but this seems to be a decent code example.

edit: Here is my own example (pseudo-ish)

Selector selector = Selector.open();

int[] ports = {4000,4001,6000};

for (int port : ports) {
   ServerSocketChannel server = ServerSocketChannel.open();
   server.configureBlocking(false);

   server.socket().bind(new InetSocketAddress(port));
// we are only interested when accept evens occur on this socket
   server.register(selector, SelectionKey.OP_ACCEPT); 
}

while (selector.isOpen()) {
   selector.select();
   Set readyKeys = selector.selectedKeys();
   Iterator iterator = readyKeys.iterator();
   while (iterator.hasNext()) {
      SelectionKey key = (SelectionKey) iterator.next();
      if (key.isAcceptable()) {
         SocketChannel client = server.accept();
         Socket socket = client.socket();
// create new thread to deal with connection (closing both socket and client when done)
      }
   }
}

// tidy up selector and channels