How can I avoid blocking with Java ServerSocket?

前端 未结 3 2162
长发绾君心
长发绾君心 2021-02-19 15:56

Im working on a socket listener that has to listen on 2 ports for 2 types of data( port 80 and port 81). These data are very similar as in the kind of operations that are perfor

3条回答
  •  半阙折子戏
    2021-02-19 16:36

    Here a little example to get started with NIO.

    It's a server listening on ports 80 and 81 and printing everything that is received on standard output. A connection is closed after receiving a packet starting with CLOSE; the whole server is shutdown after receiving a packet starting with QUIT. Missing the sending part and error handling could be a bit better. :-)

    public static void main() throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        Selector selector = Selector.open();
    
        ServerSocketChannel server1 = ServerSocketChannel.open();
        server1.configureBlocking(false);
        server1.socket().bind(new InetSocketAddress(80));
        server1.register(selector, OP_ACCEPT);
    
        ServerSocketChannel server2 = ServerSocketChannel.open();
        server2.configureBlocking(false);
        server2.socket().bind(new InetSocketAddress(81));
        server2.register(selector, OP_ACCEPT);
    
        while (true) {
            selector.select();
            Iterator iter = selector.selectedKeys().iterator();
            while (iter.hasNext()) {
                SocketChannel client;
                SelectionKey key = iter.next();
                iter.remove();
    
                switch (key.readyOps()) {
                    case OP_ACCEPT:
                        client = ((ServerSocketChannel) key.channel()).accept();
                        client.configureBlocking(false);
                        client.register(selector, OP_READ);
                        break;
                    case OP_READ:
                        client = (SocketChannel) key.channel();
                        buffer.clear();
                        if (client.read(buffer) != -1) {
                            buffer.flip();
                            String line = new String(buffer.array(), buffer.position(), buffer.remaining());
                            System.out.println(line);
                            if (line.startsWith("CLOSE")) {
                                client.close();
                            } else if (line.startsWith("QUIT")) {
                                for (SelectionKey k : selector.keys()) {
                                    k.cancel();
                                    k.channel().close();
                                }
                                selector.close();
                                return;
                            }
                        } else {
                            key.cancel();
                        }
                        break;
                    default:
                        System.out.println("unhandled " + key.readyOps());
                        break;
                }
            }
        }
    }
    

    Obs: the fields of SelectionKey (OP_ACCEPT...) are statically imported:

    import static java.nio.channels.SelectionKey.*;
    

提交回复
热议问题