目录
- Netty 的核心组件
- Bytebuf(字节容器)
- Bootstrap 和 ServerBootstrap(启动引导类)
- Channel(网络操作抽象类)
- Selector
- EventLoop(事件循环)
- NioEventLoopGroup 默认的构造函数会起多少线程?
- ChannelHandler(消息处理器) 、 ChannelPipeline(ChannelHandler 对象链表)和ChannelHandlerContext
- ChannelFuture(操作执行结果)
- Netty 是什么?BIO,NIO 和 AIO 有啥区别?
- 为什么要用 Netty?它有哪些应用场景?
- Reactor 线程模型
- Netty 线程模型
- Netty 服务端和客户端的启动过程?
- 什么是 TCP 粘包/拆包?有什么解决办法呢?
- 什么是 Netty 心跳机制、零拷贝?
- 说一说Netty中的编解码器
- 说一说Netty中Handler的执行顺序
- Netty中如何实现断线自动重连?
- Netty中使用到了哪些设计模式?
Netty 的核心组件
Bytebuf(字节容器)
网络通信最终都是通过字节流进行传输的。 ByteBuf 就是 Netty 提供的一个字节容器,其内部是一个字节数组。 当我们通过 Netty 传输数据的时候,就是通过 ByteBuf 进行的。
我们可以将 ByteBuf 看作是 Netty 对 Java NIO 提供的ByteBuffer 字节容器的封装和抽象。为什么不直接使用 Java NIO 提供的 ByteBuffer 呢?因为 ByteBuffer 这个类使用起来过于复杂和繁琐。
Bootstrap 和 ServerBootstrap(启动引导类)
Bootstrap 是客户端的启动引导类/辅助类
EventLoopGroup group = new NioEventLoopGroup();
try {//创建客户端启动引导/辅助类:BootstrapBootstrap b = new Bootstrap();//指定线程模型b.group(group).......// 尝试建立连接ChannelFuture f = b.connect(host, port).sync();f.channel().closeFuture().sync();
} finally {// 优雅关闭相关线程组资源group.shutdownGracefully();
}
ServerBootstrap 是服务端的启动引导类/辅助类
// 1.bossGroup 用于接收连接,workerGroup 用于具体的处理
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {//2.创建服务端启动引导/辅助类:ServerBootstrapServerBootstrap b = new ServerBootstrap();//3.给引导类配置两大线程组,确定了线程模型b.group(bossGroup, workerGroup).......// 6.绑定端口ChannelFuture f = b.bind(port).sync();// 等待连接关闭f.channel().closeFuture().sync();
} finally {//7.优雅关闭相关线程组资源bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();
}
- Bootstrap 通常使用 connect() 方法连接到远程的主机和端口,作为一个 Netty TCP 协议通信中的客户端。另外,Bootstrap 也可以通过 bind() 方法绑定本地的一个端口,作为 UDP 协议通信中的一端。
- ServerBootstrap通常使用 bind() 方法绑定本地的端口上,然后等待客户端的连接。
- Bootstrap 只需要配置一个线程组— EventLoopGroup ,而 ServerBootstrap需要配置两个线程组— EventLoopGroup ,一个用于接收连接,一个用于具体的 IO 处理。
Channel(网络操作抽象类)
Channel 接口是 Netty 对网络操作抽象类。通过 Channel 我们可以进行 I/O 操作。
一旦客户端成功连接服务端,就会新建一个 Channel 同该用户端进行绑定。
// 通过 Bootstrap 的 connect 方法连接到服务端
public Channel doConnect(InetSocketAddress inetSocketAddress) {CompletableFuture<Channel> completableFuture = new CompletableFuture<>();bootstrap.connect(inetSocketAddress).addListener((ChannelFutureListener)future -> {if (future.isSuccess()) {completableFuture.complete(future.channel());} else {throw new IllegalStateException();}});return completableFuture.get()