本文共 6163 字,大约阅读时间需要 20 分钟。
Netty在IDEA中搭建HelloWorld服务端并对Netty执行流程与重要组件进行介绍
Netty是一款强大的异步I/O框架,广泛应用于网络应用开发。为了帮助开发者快速入门,以下将详细介绍如何使用Netty搭建HelloWorld服务端与客户端,并实现数据传输。
场景
在本节中,我们将通过Netty实现一个简单的Socket通信应用。服务端和客户端将通过Netty进行数据的交互,展示Netty的基本功能和优势。
实现
创建服务端类
在src目录下新建包com.badao.nettySocket,并在该包下创建服务端类SocketServer。该类将继承自ServerBootstrap并包含main方法。package com.badao.nettySocket;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioServerSocketChannel;public class SocketServer { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new SocketServerInitializer()); ChannelFuture channelFuture = serverBootstrap.bind(70).sync(); channelFuture.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } }}创建服务端初始化器
服务端初始化器SocketServerInitializer继承自ChannelInitializer,并添加必要的处理器。package com.badao.nettySocket;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.LengthFieldBasedFrameDecoder;import io.netty.handler.codec.LengthFieldPrepender;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.util.CharsetUtil;public class SocketServerInitializer extends ChannelInitializer{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); pipeline.addLast(new LengthFieldPrepender(4)); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast(new SocketServerHandler()); }}
创建服务端处理器
服务端处理器SocketServerHandler继承自SimpleChannelInboundHandler,用于处理客户端发送的数据。package com.badao.nettySocket;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;public class SocketServerHandler extends SimpleChannelInboundHandler{ @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println("服务端收到来自" + ctx.channel().remoteAddress() + "的" + msg); ctx.channel().writeAndFlush("服务端发送的数据:(公众号:霸道的程序猿)"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); }}
创建客户端类
在com.badao.nettySocket包下创建客户端类SocketClient,该类继承自Bootstrap并包含main方法。package com.badao.nettySocket;import io.netty.bootstrap.Bootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.nio.NioSocketChannel;public class SocketClient { public static void main(String[] args) throws Exception { EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class) .handler(new SocketClientInitializer()); ChannelFuture channelFuture = bootstrap.connect("localhost", 70).sync(); channelFuture.channel().closeFuture().sync(); } finally { eventLoopGroup.shutdownGracefully(); } }}创建客户端初始化器
客户端初始化器SocketClientInitializer继承自ChannelInitializer,并添加必要的处理器。package com.badao.nettySocket;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.LengthFieldBasedFrameDecoder;import io.netty.handler.codec.LengthFieldPrepender;import io.netty.handler.codec.string.StringDecoder;import io.netty.handler.codec.string.StringEncoder;import io.netty.util.CharsetUtil;public class SocketClientInitializer extends ChannelInitializer{ @Override protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)); pipeline.addLast(new LengthFieldPrepender(4)); pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8)); pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8)); pipeline.addLast(new SocketClientHandler()); }}
创建客户端处理器
客户端处理器SocketClientHandler继承自SimpleChannelInboundHandler,用于处理服务端发送的数据。package com.badao.nettySocket;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;public class SocketClientHandler extends SimpleChannelInboundHandler{ @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println("客户端收到来自" + ctx.channel().remoteAddress() + "的" + msg); ctx.channel().writeAndFlush("客户端向服务端发送的数据:(公众号:霸道的程序猿)"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); }}
在客户端的channelActive方法中添加数据发送逻辑,确保客户端在连接建立后立即发送数据。
@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception { ctx.writeAndFlush("客户端发来消息");} 通过以上步骤,服务端和客户端的通信流程如下:
channelActive方法中发送数据,触发服务端处理。运行与调试
main方法。通过以上步骤,您成功搭建并实现了一个使用Netty的Socket通信应用,展示了服务端与客户端之间的数据传输流程。Netty的强大功能使得开发高性能网络应用变得更加容易,同时代码的可读性和可维护性也得到了提升。
转载地址:http://mvcfk.baihongyu.com/