NIO服务

2018-06-21  本文已影响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餐厅一个服务员(thread)服务一个客人(client) 而NIO餐厅一个服务员(thread)服务多个客人(clients)

References

上一篇下一篇

猜你喜欢

热点阅读