Netty (1) -BIO, NIO and Netty entry

client-server mode in a communication .BIO

BIO i.e. Blocking IO, blocking the IO synchronization, in the communication mode of BIO,
"A thread can be in one accept, read or write method of blocking, corresponding to a line connecting IO"
Here Insert Picture Description
I.e. the client program in the server mode communication BIO:

  • BIOClient
/**
 * @Auther: ARong
 * @Description: BIO 的 客户端
 */
public class BIOClient {
    public static void main(String[] args) throws IOException, InterruptedException {
        Socket socket = new Socket("127.0.0.1", 6666);
        // 每2s向服务端发送helloword
        for (int i = 0; i < 10; i++) {
            Thread.sleep(2*1000);
            String message = String.format("HelloWorld From %s", new SimpleDateFormat("hh:mm:ss").format(new Date()));
            socket.getOutputStream().write(message.getBytes());
        }
    }
}
  • BIOServer
/**
 * @Auther: ARong
 * @Description: BIO 的 服务端
 */
public class BIOServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(6666);
        while (true) {
            // 阻塞直到有客户端连接
            Socket socket = serverSocket.accept();
            // 每次有连接即创建一个线程接受处理
            new Thread(()->{
                // 处理请求
                int len = -1;
                byte[] data = new byte[1024];//每次读取1kb
                try {
                    InputStream inputStream = socket.getInputStream();
                    while ((len = inputStream.read(data)) != -1) {
                        System.out.println(new String(data, 0, len));
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

The traditional model for each successful connection is established BIO needs to maintain a thread, each thread contains a while loop, then the corresponding connections 1w 1w threads, and then bring the following issues 1w a while infinite loop:

  1. Thread resource-constrained: Thread the operating system is a very valuable resource, the same time a large number of threads in the blocked state is very serious waste of resources, the operating system can not afford to consume
  2. Low thread switching efficiency: Single CPU core fixed number, after the explosion of the operating system threads frequent thread switching, a sharp decline in application performance
  3. Data is read in units of a byte stream is not efficient: Each time a byte is one byte of data read from the underlying operating system

Second communication mode .NIO

New IO or NIO i.e. NoBloking-IO, synchronous non-blocking IO, which isBased Buffer, Channel Selector and the "IO multiplexing communication mode, a thread is not blocked in accpet, read or write method, but can handle multiple IO lines connected at the same time."
Here Insert Picture Description
NIO compared to the advantages of BIO are:

  1. Only a small amount of the thread, through the IO multiplexed fashion to process the plurality of IO, IO without blocking in a connection, a thread context switch would not present problems, improve the communication efficiency
  2. Byte stream data read as a unit no longer, but in units of blocks read and write buffer

The following is a Java implementation of NIO Demo

  • NIOServer (Copy From Flash)
public class NIOServer {

    /**
     * serverSelector负责轮询是否有新的连接,clientSelector负责轮询连接是否有数据可读.
     * 服务端监测到新的连接不再创建一个新的线程,而是直接将新连接绑定到clientSelector上,这样不用IO模型中1w个while循环在死等
     * clientSelector被一个while死循环包裹,如果在某一时刻有多条连接有数据可读通过 clientSelector.select(1)方法轮询出来进而批量处理
     * 数据的读写以内存块为单位
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        Selector serverSelector = Selector.open();
        Selector clientSelector = Selector.open();

        new Thread(() -> {
            try {
                ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
                serverSocketChannel.socket().bind(new InetSocketAddress(8000));
                serverSocketChannel.configureBlocking(false);
                serverSocketChannel.register(serverSelector, SelectionKey.OP_ACCEPT);

                while (true) {
                    // 轮询监测是否有新的连接
                    if (serverSelector.select(1) > 0) {
                        Set<SelectionKey> selectionKeys = serverSelector.selectedKeys();
                        Iterator<SelectionKey> keyIterator;
                        keyIterator = selectionKeys.iterator();
                        while (keyIterator.hasNext()) {
                            SelectionKey selectionKey = keyIterator.next();
                            if (selectionKey.isAcceptable()) {
                                try {
                                    //(1)每来一个新连接不需要创建一个线程而是直接注册到clientSelector
                                    SocketChannel socketChannel = ((ServerSocketChannel) selectionKey.channel()).accept();
                                    socketChannel.configureBlocking(false);
                                    socketChannel.register(clientSelector, SelectionKey.OP_READ);
                                } finally {
                                    keyIterator.remove();
                                }
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                while (true) {
                    // (2)批量轮询是否有哪些连接有数据可读
                    if (clientSelector.select(1) > 0) {
                        Set<SelectionKey> selectionKeys = serverSelector.selectedKeys();
                        Iterator<SelectionKey> keyIterator = selectionKeys.iterator();
                        while (keyIterator.hasNext()) {
                            SelectionKey selectionKey = keyIterator.next();
                            if (selectionKey.isReadable()) {
                                try {
                                    SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                                    ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
                                    //(3)读取数据以块为单位批量读取
                                    socketChannel.read(byteBuffer);
                                    byteBuffer.flip();
                                    System.out.println(Charset.defaultCharset().newDecoder().decode(byteBuffer)
                                            .toString());
                                } finally {
                                    keyIterator.remove();
                                    selectionKey.interestOps(SelectionKey.OP_READ);
                                }
                            }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

Getting three .Netty

1. What is Netty

Netty is an asynchronous communication framework based on Java NIO libraries, its architecture is characterized by: non-blocking asynchronous, event-driven, high performance, high reliability and high customizability. Netty use can be a good alternative out cumbersome, difficult to use the Java NIO libraries, and Netty provides more functions available.

The practical application of 2.Netty

  1. High-performance HTTP server
  2. High performance RPC frame (e.g. Dubbo)
  3. Redission(Redis For Java)
  4. IM instant messaging application
  5. It requires a large number of underlying network communication frame to achieve

3.Netty Getting Started Demo

  1. Import dependence maven
<!-- https://mvnrepository.com/artifact/io.netty/netty-all -->
<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.42.Final</version>
</dependency>
  1. NIOServer
public class NIOServer {
    public static void main(String[] args) {
        ServerBootstrap serverBootstrap = new ServerBootstrap();
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(); // 监听组
        NioEventLoopGroup workerGroup = new NioEventLoopGroup(); // 工作组

        serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class) //NIO模式
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    // 初始化channel
                    protected void initChannel(SocketChannel ch) throws Exception {
                        ch.pipeline().addLast(new StringDecoder());
                        ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
                                System.out.println(String.format("服务端接收到消息:%s", msg));
                            }
                        });
                    }
                }).bind(8000);
    }
}
  1. NIOCLient
public class NIOClient {
    public static void main(String[] args) throws InterruptedException {
        Bootstrap bootstrap = new Bootstrap();
        NioEventLoopGroup group = new NioEventLoopGroup();

        bootstrap.group(group).channel(NioSocketChannel.class).handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ch.pipeline().addLast(new StringEncoder());
            }
        });

        Channel channel = bootstrap.connect("127.0.0.1", 8000).channel();
        while (true) {
            String message = String.format("HelloWorld From %s", new SimpleDateFormat("hh:mm:ss").format(new Date()));
            channel.writeAndFlush(message);
            Thread.sleep(2000);
        }
    }
}

execute program:

Here Insert Picture Description

Published 309 original articles · won praise 205 · Views 300,000 +

Guess you like

Origin blog.csdn.net/pbrlovejava/article/details/104148009