📝个人主页:五敷有你
🔥系列专栏:Netty
⛺️稳中求进,晒太阳
加入依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.39.Final</version>
</dependency>
服务器端
new ServerBootstrap()
.group(new NioEventLoopGroup()) // 1
.channel(NioServerSocketChannel.class) // 2
.childHandler(new ChannelInitializer<NioSocketChannel>() { // 3
protected void initChannel(NioSocketChannel ch) {
ch.pipeline().addLast(new StringDecoder()); // 5
ch.pipeline().addLast(new SimpleChannelInboundHandler<String>() { // 6
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
System.out.println(msg);
}
});
}
})
.bind(8080); // 4
代码解读:
1:创建NioEventLoopGroup ,可以理解为线程池+selector。
2:选择服务socket实现类,其中NioServerSocketChannel表示基于NIO的服务器端来实现,其他实现还有
3:为什么方法叫childHandler,是接下来添加的处理器都是给SocketChannel用的,不是给ServerSocketChannel。ChannelInitializer处理器(仅执行一次),它的作用是等待客户端SocketChannel建立连接后,执行initChannel以便添加更多处理器。
4:ServerSocketChannel 绑定的监听端口
5:SocketChannel 的处理器,解码 ByteBuf => String
6:SocketChannel 的业务处理器,使用上一个处理器的处理结果
客户端
new Bootstrap()
.group(new NioEventLoopGroup()) // 1
.channel(NioSocketChannel.class) // 2
.handler(new ChannelInitializer<Channel>() { // 3
@Override
protected void initChannel(Channel ch) {
ch.pipeline().addLast(new StringEncoder()); // 8
}
})
.connect("127.0.0.1", 8080) // 4
.sync() // 5
.channel() // 6
.writeAndFlush(new Date() + ": hello world!"); // 7
代码解读:
1:创建NioEventLoopGroup
2: 选择客户端Socket实现类,NioSocketChannel表示基于NIO的客户端实现。
其它实现还有
3 :添加 SocketChannel 的处理器,ChannelInitializer 处理器(仅执行一次),它的作用是待客户端 SocketChannel 建立连接后,执行 initChannel 以便添加更多的处理器
4:指定连接的端口和服务器
5:Netty中有很多方法是异步的,如connect,这时候使用sync.方法等待connect建立连接完毕。
6:获取 channel 对象,它即为通道抽象,可以进行数据读写操作
7:写入消息清空缓冲区
8:消息会经过通道 handler 处理,这里是将 String => ByteBuf 发出
9:数据经过网络传输,到达服务器端,服务器端 5 和 6 处的 handler 先后被触发,走完一个流程