技术整理分享:nio和netty
https://tieba.baidu.com/p/6082929153?red_tag=2754348730
总结:
NIO(Non - blocking I/O)详解
概述
NIO 是 Java 1.4 引入的新 I/O 模型,与传统的阻塞 I/O(BIO)不同,NIO 是基于通道(Channel)和缓冲区(Buffer)进行操作的,并且支持非阻塞通信,能够显著提高程序的并发处理能力和性能。
核心组件及原理
- 缓冲区(Buffer):是一个用于存储数据的容器,本质上是一个数组,例如
ByteBuffer
、CharBuffer
等。数据可以从通道读取到缓冲区,也可以从缓冲区写入通道。 - 通道(Channel):可以看作是数据传输的管道,用于连接数据源和数据目的地。常见的通道有
FileChannel
(用于文件读写)、SocketChannel
(用于网络通信)等。 - 选择器(Selector):是 NIO 实现非阻塞的关键。一个选择器可以监听多个通道的 I/O 事件(如读、写、连接等),当某个通道有事件发生时,选择器会将其选中,程序可以对这些事件进行处理。
举例说明
以下是一个简单的 NIO 文件读取示例:
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class NIOFileReadExample {
public static void main(String[] args) {
try (FileInputStream fis = new FileInputStream("test.txt");
FileChannel channel = fis.getChannel()) {
// 创建一个容量为 1024 的 ByteBuffer
ByteBuffer buffer = ByteBuffer.allocate(1024);
// 从通道读取数据到缓冲区
int bytesRead = channel.read(buffer);
while (bytesRead != -1) {
// 切换缓冲区为读模式
buffer.flip();
while (buffer.hasRemaining()) {
System.out.print((char) buffer.get());
}
// 清空缓冲区
buffer.clear();
bytesRead = channel.read(buffer);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
在这个例子中,首先创建了一个 FileInputStream
和对应的 FileChannel
,然后创建了一个 ByteBuffer
用于存储从文件中读取的数据。通过 channel.read(buffer)
方法将数据从通道读取到缓冲区,再将缓冲区的数据输出。
Netty 详解
概述
Netty 是一个基于 Java NIO 实现的高性能网络编程框架,它简化了网络编程的复杂性,提供了易于使用的 API,同时具有高吞吐量、低延迟等特点,广泛应用于开发网络服务器和客户端程序。
核心组件及原理
- Channel:Netty 中的通道,类似于 NIO 中的通道,用于网络数据的读写。
- EventLoop:是 Netty 的事件循环器,负责处理通道的 I/O 事件和任务调度。一个
EventLoop
可以处理多个通道的事件。 - ChannelPipeline:是一个
ChannelHandler
的链表,每个ChannelHandler
负责处理特定的业务逻辑,如数据的编解码、业务处理等。当有数据在通道中流动时,会依次经过ChannelPipeline
中的各个ChannelHandler
。
举例说明
以下是一个简单的 Netty 服务器示例:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class NettyServer {
private final int port;
public NettyServer(int port) {
this.port = port;
}
public void run() throws Exception {
// 创建两个 EventLoopGroup,一个用于接受客户端连接,一个用于处理网络读写
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new NettyServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
// 绑定端口,开始接收进来的连接
ChannelFuture f = b.bind(port).sync();
// 等待服务器 socket 关闭 。
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws Exception {
int port = 8080;
new NettyServer(port).run();
}
}
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class NettyServerHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("Received from client: " + msg);
ctx.writeAndFlush("Server received: " + msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
在这个例子中,创建了两个 EventLoopGroup
,分别用于接受客户端连接和处理网络读写。ServerBootstrap
用于启动服务器,通过 childHandler
方法配置 ChannelPipeline
,添加了字符串编解码器和自定义的 NettyServerHandler
。当客户端发送消息时,NettyServerHandler
会接收消息并将处理结果返回给客户端。
总结
NIO 是 Java 提供的非阻塞 I/O 模型,为高性能网络编程提供了基础。而 Netty 是基于 NIO 构建的高性能网络编程框架,它简化了 NIO 的使用,让开发者可以更方便地开发网络应用程序。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通