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:
x
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.
It's not possible to for a single instance of ServerSocket
to listen to multiple ports. You can of course have multiple ServerSocket
s. 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