之前用Netty写过一些简单的应用,包括etakeaway(我的非开源作品)的IM系统,还有xxx水库预测(非开源商业作品)传感器数据对接等。但是一直使用的是最基础的功能,也都是一些并发量不是很大的应用,有点强上的感觉,遂打算系统学习一下netty,最近不是很沉得下心学东西,都是在写自己的小网站,持续跟进导师项目,只能拿出一些零碎的时间沉下心来学习,Netty我不会仔细记录,只会记录学习过程中的一些demo和感悟
第一个demo是echo服务器,刚开始学linux网络编程的时候也是写这个东西,那个时候大一,用c语言,转眼就快大三了
首先是Server代码
javapackage org.example.demo1_echo_server.server;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
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 EchoServer {
private final int port; // 监听端口
public EchoServer(int port) {
this.port = port;
}
public void start() throws InterruptedException {
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 {
ChannelPipeline p = ch.pipeline();
p.addLast(new StringDecoder());
p.addLast(new StringEncoder());
p.addLast(new EchoServerHandler());
}
});
ChannelFuture f = b.bind(port).sync();
System.out.println("EchoServer started on port " + port);
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
int port = 8080;
new EchoServer(port).start();
}
}
package org.example.demo1_echo_server.server;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class EchoServerHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("Received message: " + msg);
ctx.writeAndFlush("热死了,一点都不好!"); // Echo back the received message to the client
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
client端
javapackage org.example.demo1_echo_server.client;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class EchoClient {
private final String host;
private final int port;
public EchoClient(String host, int port) {
this.host = host;
this.port = port;
}
public void start() throws InterruptedException {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new StringDecoder());
p.addLast(new StringEncoder());
p.addLast(new EchoClientHandler());
}
});
ChannelFuture f = b.connect(host, port).sync();
System.out.println("EchoClient connected to " + host + ":" + port);
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
String host = "localhost";
int port = 8080;
new EchoClient(host, port).start();
}
}
package org.example.demo1_echo_server.client;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
public class EchoClientHandler extends SimpleChannelInboundHandler<String> {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush("有一个客户端已经建立连接!"); // Send a message to the server when the channel is active
ctx.writeAndFlush("你好,我是yowayimono!");
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("Received echo: " + msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
简单的观察一下上面的结构,我们可以得到一个大概的Netty的基本组件,总结如下
1. Bootstrap 和 ServerBootstrap
Bootstrap:用于客户端配置和启动。它简化了 Netty 客户端的创建过程,负责配置和连接到服务器。
ServerBootstrap:用于服务器端配置和启动。它简化了 Netty 服务器的创建过程,负责绑定端口和接受客户端连接。
2. Channel
3. ChannelHandler
4. ChannelPipeline
5. EventLoop
6. ChannelFuture
本文作者:yowayimono
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!