1 介绍
1.1 Netty优势
API使用简单,开发门槛低
功能强大,支持多种主流协议
定制能力强,通过channel Handler对通信框架进行灵活的拓展
性能高,通过与其它主流NIO框架相比,Netty性能最优
成熟、稳定
社区活跃,版本迭代周期短,发现的BUG可以被及时的修复
1.2 Netty核心组件
Bootstrap:启动类和主入口类;客户端和服务端的
EventLoop:线程,将channel发生的事件做循环处理
EventLoopGroup:线程组
Channel:Socket/SocketChannel
事件:网络上发生的事包装成事件;入站事件/出站事件
ChannelHandler:处理事件(加密、压缩等)
ChannelPipeline:一个个 ChannelHandler 构成的链路;责任链模式/过滤器
ChannelFuture:获取异步执行的结果
2 实战
2.1 服务端
public class Server {
private final int port = 8080;
public static void main(String[] args) throws InterruptedException {
Server server = new Server();
server.start();
}
public void start() throws InterruptedException {
//线程组
NioEventLoopGroup group = new NioEventLoopGroup();
//服务端启动必备
ServerBootstrap bootstrap = new ServerBootstrap();
try {
bootstrap.group(group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(port))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ServerHandler());
}
});
//异步绑定服务器,阻塞直到完成
ChannelFuture future = bootstrap.bind().sync();
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
public class ServerHandler extends ChannelInboundHandlerAdapter {
//读取客户端传的数据
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg/*传递的消息*/) throws Exception {
ByteBuf in = (ByteBuf) msg;
System.out.println("Server accept :" + in.toString(StandardCharsets.UTF_8));
ctx.writeAndFlush(in);
ctx.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
2.2 客户端
public class Client {
private final int port = 8080;
private final String host = "127.0.0.1";
public static void main(String[] args) throws InterruptedException {
new Client().start();
}
public void start() throws InterruptedException {
//Group线程组
NioEventLoopGroup group = new NioEventLoopGroup();
//客户端启动类
Bootstrap bootstrap = new Bootstrap();
try {
bootstrap.group(group)
.channel(NioSocketChannel.class)
//指定服务器的IP地址和端口,和服务器的不同
.remoteAddress(new InetSocketAddress(host, port))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture future = bootstrap.connect().sync();
future.channel().closeFuture().sync();
} finally {
group.shutdownGracefully().sync();
}
}
}
public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
System.out.println("client Accept" + msg.toString(CharsetUtil.UTF_8));
ctx.close();
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush(Unpooled.copiedBuffer("Hello Netty", CharsetUtil.UTF_8));
}
}