BIO,NIO,Netty的区别

为什么80%的码农都做不了架构师?>>>   hot3.png

1.BIO的例子。

/**
 * @author lilinshen
 * @title bio (Blocking io) 同步阻塞io
 * @description jdk1.4 io 都是bio
 * @date 2018/8/21 15:02
 */
public class BIOServer {
    public static void main(String[] args) {
        server1();
    }

    /**
     * 传统,只能是1对1
     */
    public static void server1() {
        ServerSocket server = null;
        Socket socket = null;
        InputStream in = null;
        OutputStream out = null;
        try {
            server = new ServerSocket(8000);
            System.out.println("服务端启动成功,监听端口为8000,等待客户端连接...");

            socket = server.accept(); //阻塞 客户端
            in = socket.getInputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            //读取客户端的数据
            while ((len = in.read(buffer)) > 0) {
                System.out.println(new String(buffer, 0, len));
            }
            //向客户端写数据
            out = socket.getOutputStream();
            out.write("hello everybody!".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 多线程
     */
    public static void server2() {
        ServerSocket server = null;
        try {
            server = new ServerSocket(8000);
            System.out.println("服务端启动成功,监听端口为8000,等待客户端连接...");
            while (true) {
                Socket socket = new Socket();
                //针对每个连接创建一个线程,去处理io操作
                //socket来了之后就创建线程  不合理
                new Thread(new BIOServerHandler(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 线程池
     */
    public static void server3() {
        ServerSocket server = null;
        ExecutorService executorService = Executors.newFixedThreadPool(60);
        try {
            server = new ServerSocket(8000);
            System.out.println("服务端启动成功,监听端口为8000,等待客户端连接...");
            while (true) {
                Socket socket = new Socket();
                //使用线程池中的线程去执行每个对应的任务
                executorService.execute(new BIOServerHandler(socket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
/**
 * @author lilinshen
 * @title bio serverhandler
 * @description 请填写相关描述
 * @date 2018/8/21 15:20
 */
public class BIOServerHandler implements Runnable {
    private Socket socket;

    public BIOServerHandler(Socket socket) {
        this.socket = socket;
    }

    /**
     * 当前线程要执行的任务
     */
    @Override
    public void run() {
        InputStream in = null;
        try {
            in = socket.getInputStream();
            byte[] buffer = new byte[1024];
            int len = 0;
            //读取客户端的数据
            while ((len = in.read(buffer)) > 0) {
                System.out.println(new String(buffer, 0, len));
            }
            //向客户端写数据
            OutputStream out = socket.getOutputStream();
            out.write("hello everybody!".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

2.nio例子

/**
 * @author lilinshen
 * @title nio 同步非阻塞
 * @description 是对bio的改进,但是api比较复杂。
 * @date 2018/8/21 15:53
 */
public class NIOServer {
    private int port;
    private InetSocketAddress address = null;
    private Selector selector;

    public NIOServer(int port) {
        try {
            this.port = port;
            address = new InetSocketAddress(this.port);
            ServerSocketChannel server = ServerSocketChannel.open();
            //服务器通道设置成非阻塞的模式
            //server.configureBlocking(false);
            server.socket().bind(address);
            selector = Selector.open();
            //每当有客户端连接上来的时候,默认它已经连接上来了
            //而这个连接我需要记录一个它的状态  connected
            server.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("服务器启动成功:" + this.port);

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //Selector开始轮询
    public void listen() {
        try {
            while (true) {
                //accept()阻塞的,select()也是阻塞的
                int wait = this.selector.select();
                if (wait == 0) {
                    continue;
                }
                //SelectionKey代表的是客户端和服务端连接的一个关键
                Set keys = this.selector.selectedKeys();
                Iterator i = keys.iterator();
                while (i.hasNext()) {
                    SelectionKey key = i.next();
                    //针对每一个客户端进行相应的操作
                    process(key);
                    i.remove();
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    //处理每一个客户端 key
    private void process(SelectionKey key) throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        if (key.isAcceptable()) {
            ServerSocketChannel server = (ServerSocketChannel) key.channel();
            SocketChannel client = server.accept();
            client.configureBlocking(false);
            //客户端一旦连接上来  读写
            //往这个selector上注册key  read   接下来可以读
            client.register(selector, SelectionKey.OP_READ);
        } else if (key.isReadable()) {
            SocketChannel client = (SocketChannel) key.channel();
            int len = client.read(buffer);
            //读取完成了
            if (len > 0) {
                buffer.flip(); //固定
                String content = new String(buffer.array(), 0, len);
                client.register(selector, SelectionKey.OP_WRITE);
                System.out.println(content);
            }
            buffer.clear();
        } else if (key.isWritable()) {
            SocketChannel client = (SocketChannel) key.channel();
            client.write(buffer.wrap("hello world".getBytes()));
            client.close();
        }
    }

    public static void main(String[] args) {
        new NIOServer(8000).listen();
    }

}

3.netty例子

/**
 * @author lilinshen
 * @title netty 异步非阻塞
 * @description 是对nio的封装,新增了异步。
 * @date 2018/8/21 16:44
 */
public class NettyServer {

    /**
     * netty 异步非阻塞
     * 在nio中的selector.select() 使用了多线程。
     */
    public static void server() {
        //Boss线程
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline().addLast(new HttpRequestEncoder());
                            ch.pipeline().addLast(new HttpRequestDecoder());
                            //添加自己的handler
                            //...
                        }
                    }).option(ChannelOption.SO_BACKLOG, 128).childOption(ChannelOption.SO_KEEPALIVE, true);
            //绑定服务端口  阻塞的过程
            System.out.println("服务端开启等待客户端连接...");
            ChannelFuture f = b.bind(8000).sync();
            //开始接收客户端
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 优雅的推出程序
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }

    public static void main(String[] args) {
        server();
    }

}

 

转载于:https://my.oschina.net/llsydn/blog/1931623

你可能感兴趣的:(BIO,NIO,Netty的区别)