Netty 学习:服务端启动 & 客户端启动

说明

Netty 封装了 Java NIO 的很多功能,大大简化了 Java 网络编程的难度,同时 Netty 也支持多种协议,Netty 架构图如下

Netty 学习:服务端启动 & 客户端启动_第1张图片

注:上图来自 Netty 官网

BIO 模型

传统的Java BIO模型代码如下

客户端代码

import java.net.Socket;
import java.util.Date;

/**
 * 传统 BIO 的客户端实现
 *
 * @author Grey
 * @date 2022/9/12
 * @since 1.1
 */
public class IOClient {
    public static void main(String[] args) {
        new Thread(() -> {
            try {
                Socket socket = new Socket("127.0.0.1", 8000);
                while (true) {
                    try {
                        socket.getOutputStream().write((new Date() + ": hello world").getBytes());
                        Thread.sleep(2000);
                    } catch (Exception e) {
                    }
                }
            } catch (Exception e) {

            }
        }).start();
    }
}

服务端代码

package bio;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 传统 BIO 的 服务端实现
 *
 * @author Grey
 * @date 2022/9/12
 * @since 1.1
 */
public class IOServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8000);
        new Thread(() -> {
            while (true) {
                try {
                    // 阻塞
                    Socket socket = serverSocket.accept();
                    new Thread(() -> {
                        try {
                            int len;
                            byte[] data = new byte[1024];
                            InputStream inputStream = socket.getInputStream();
                            // 按照字节流的方式读取数据
                            while ((len = inputStream.read(data)) != -1) {
                                System.out.println(new String(data, 0, len));
                            }
                        } catch (IOException e) {

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

                }
            }
        }).start();
    }
}

上述代码比较直白,缺点也很明显

每个连接创建成功后都需要由一个线程来维护,同一时刻有大量线程处于阻塞状态,此外,线程数量太多,也会导致操作系统频繁进行线程切换,使得应用性能下降。

NIO 模型

为了解决 BIO 的问题,引入了 NIO,即:一个新的连接来了以后,不会创建一个while 死循环取监听有数据可读,而是直接把这条连接注册到 Selector 上。然后,通过检查这个 Selector,就可以批量监测出有数据可读的连接,进而读取数据。

BIO读写是面向流的,一次性只能从流中读取一个字节或者多字节,并且读完之后流无法再读取,需要自己缓存数据。而 NIO 的读写是面向 Buffer 的,可以随意读取里面任何字节的数据,不需要自己缓存数据,只需要移动读写指针即可。

但是 Java 原生的 NIO 代码编程非常繁琐,一个简单的服务端代码,使用 NIO 模型,代码如下

package nio;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selecto

你可能感兴趣的:(java,jvm,servlet)