Search code examples
javamultithreadingtcpserversocket

Java Server - Multiple ports?


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.


Solution

  • 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