NIO服务

作者: 诺之林 | 来源:发表于2018-06-21 11:24 被阅读24次

    本文开发语言基于Java 代码参考SocketServer

    目录

    OIO

    OIO: Old IO or Blocking IO

    Sync

    vim OIOServer.java
    
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class OIOServer {
    
        @SuppressWarnings("resource")
        public static void main(String[] args) throws Exception {
            ServerSocket server = new ServerSocket(10001);
            System.out.println("server start");
            while (true) {
                Socket socket = server.accept();
                System.out.println("a client connected");
                handler(socket);
            }
        }
    
        public static void handler(Socket socket) {
            try {
                byte[] bytes = new byte[1024];
                InputStream inputStream = socket.getInputStream();
    
                while (true) {
                    int read = inputStream.read(bytes);
                    if (read != -1) {
                        System.out.println(new String(bytes, 0, read).trim());
                    } else {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    System.out.println("a client closed");
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    # server
    javac OIOServer.java && java OIOServer
    
    # client 1
    telnet 127.0.0.1 10001
    
    # client 2
    telnet 127.0.0.1 10001
    
    # server
    server start
    a client connected
    hello
    world
    
    # client 1
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    hello
    world
    
    # client 2
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    

    Mac OS安装telnet: brew install telnet

    Async

    vim OIOServer.java
    
    import java.io.InputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class OIOServer {
    
        @SuppressWarnings("resource")
        public static void main(String[] args) throws Exception {
            ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
            ServerSocket server = new ServerSocket(10001);
            System.out.println("server start");
            while (true) {
                final Socket socket = server.accept();
                System.out.println("a client connected");
                newCachedThreadPool.execute(new Runnable() {
                    @Override
                    public void run() {
                        handler(socket);
                    }
                });
            }
        }
    
        public static void handler(Socket socket) {
            try {
                byte[] bytes = new byte[1024];
                InputStream inputStream = socket.getInputStream();
    
                while (true) {
                    int read = inputStream.read(bytes);
                    if (read != -1) {
                        System.out.println(new String(bytes, 0, read));
                    } else {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    System.out.println("a client closed");
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    # server
    javac OIOServer.java && java OIOServer
    
    # client 1
    telnet 127.0.0.1 10001
    
    # client 2
    telnet 127.0.0.1 10001
    
    # server
    server start
    a client connected
    hello
    world
    a client connected
    hello
    world
    
    # client 1
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    hello
    world
    
    # client 2
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    hello
    world
    

    NIO

    NIO: New IO

    vim NIOServer.java
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.SelectionKey;
    import java.nio.channels.Selector;
    import java.nio.channels.ServerSocketChannel;
    import java.nio.channels.SocketChannel;
    import java.util.Iterator;
    
    public class NIOServer {
    
        private Selector selector;
    
        public void init(int port) throws IOException {
            ServerSocketChannel server = ServerSocketChannel.open();
            server.configureBlocking(false);
            server.socket().bind(new InetSocketAddress(port));
            this.selector = Selector.open();
            server.register(selector, SelectionKey.OP_ACCEPT);
        }
    
        public void listen() throws IOException {
            System.out.println("server start");
            while (true) {
                selector.select();
    
                Iterator<?> iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = (SelectionKey) iterator.next();
                    iterator.remove();
    
                    if (key.isAcceptable()) {
                        handlerAccept(key);
                    } else if (key.isReadable()) {
                        handelerRead(key);
                    }
                }
            }
        }
    
        public void handlerAccept(SelectionKey key) throws IOException {
            System.out.println("a client connected");
            ServerSocketChannel server = (ServerSocketChannel) key.channel();
            SocketChannel channel = server.accept();
            channel.configureBlocking(false);
            channel.register(selector, SelectionKey.OP_READ);
        }
    
        public void handelerRead(SelectionKey key) throws IOException {
            SocketChannel channel = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int read = channel.read(buffer);
            if (read != -1) {
                String message = new String(buffer.array()).trim();
                System.out.println(message);
            } else {
                System.out.println("a client closed");
                key.cancel();
            }
        }
    
        public static void main(String[] args) throws Exception {
            NIOServer server = new NIOServer();
            server.init(10001);
            server.listen();
        }
    }
    
    # server
    javac NIOServer.java && java NIOServer
    
    # client 1
    telnet 127.0.0.1 10001
    
    # client 2
    telnet 127.0.0.1 10001
    
    # server
    server start
    a client connected
    hello
    world
    a client connected
    hello
    world
    
    # client 1
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    hello
    world
    
    # client 2
    Trying 127.0.0.1...
    Connected to localhost.
    Escape character is '^]'.
    hello
    world
    

    小结

    • OIO: Number of threads = Number of clients/sockets active

    • NIO: Number of threads < Number of clients/sockets active

    OIO餐厅一个服务员(thread)服务一个客人(client) 而NIO餐厅一个服务员(thread)服务多个客人(clients)

    References

    相关文章

      网友评论

          本文标题:NIO服务

          本文链接:https://www.haomeiwen.com/subject/sozzeftx.html