How to make this non-blocking server multithreaded?

I am trying to allow multiple connections to a small application such as a Java server. It works fine as it is, but if one connection opens and then freezes, all subsequent connections will hang. I'm not sure how to handle each connection, up to about 20 simultaneous in its thread, tracking which thread belongs to the client, etc. The code I have so far is:

private void init() {
    try {
        // Create the server socket channel
        ServerSocketChannel server = ServerSocketChannel.open();
        // nonblocking I/O
        server.configureBlocking(false);
        // host-port 
        server.socket().bind(new InetSocketAddress(host, port));
        System.out.println("Server connected on " + host + ":" + port);
        // Create the selector
        Selector selector = Selector.open();
        // Recording server to selector (type OP_ACCEPT)
        server.register(selector, SelectionKey.OP_ACCEPT);
        // Infinite server loop
        for (;;) {
            // Waiting for events
            selector.select();
            // Get keys
            Set keys = selector.selectedKeys();
            Iterator i = keys.iterator();
            // For each keys...
            while (i.hasNext()) {
                SelectionKey key = (SelectionKey) i.next();
                // Remove the current key
                i.remove();
                // if isAccetable = true
                // then a client required a connection
                if (key.isAcceptable()) {
                    // get client socket channel
                    SocketChannel client = server.accept();
                    // Non Blocking I/O
                    client.configureBlocking(false);
                    // recording to the selector (reading)
                    client.register(selector, SelectionKey.OP_READ);
                    continue;
                }
                // then the server is ready to read
                if (key.isReadable()) {
                    SocketChannel client = (SocketChannel) key.channel();
                    // Read byte coming from the client
                    int BUFFER_SIZE = 32;
                    ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
                    try {
                        client.read(buffer);
                    } catch (Exception e) {
                        // client is no longer active
                        e.printStackTrace();
                        continue;
                    }
                    buffer.flip();
                    Charset charset = Charset.forName("ISO-8859-1");
                    CharsetDecoder decoder = charset.newDecoder();
                    CharBuffer charBuffer = decoder.decode(buffer);
                    Handler dataHandler = new Handler();
                    client.write(ByteBuffer.wrap(dataHandler.processInput(charBuffer.toString()).getBytes()));
                    client.socket().close();
                    continue;
                }
            }
        }
    } catch (IOException ex) {
        Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
    }
}
+3
source share
3 answers

Netty Executor, ThreadPool. Netty-, ChannelBuffer. .

examples

+1

, , JVM- - .

Apache Mina. ia Java .

Mina , (IoFilters, ), .

+3

If you really don't want to write an NIO server as a training exercise, I would recommend using Netty . Like Mina, which Peter mentioned, it is also a library for writing high-performance servers.

I recently switched from using my own NIO code to this library, and it made my code so much cleaner.

+2
source

Source: https://habr.com/ru/post/1787896/


All Articles