Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
Netty是一个异步事件驱动的网络应用框架,用于快速开发可维护的高性能协议服务器和客户端。
提起Netty,我对其的了解只是停留在其对NIO进行了封装,但具体是个什么样的框架以及如何使用还是知之甚少,
最近在工作之余对其进行学习,由于是初学者,难免会有不足的地方,欢迎大家指正。好了,废话不多说了,开始正
题。
1、准备工作
一款编辑器(本人使用的是idea)
Netty4
2、该程序分为服务端和客户端,客户端向服务端发送 HELLO NETTY请求,服务端响应客户端 WELCOM TO NETTY。本程序使用的是Netty4。具体代码如下:
创建Maven项目,并添加Netty依赖
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.10.final</version> </dependency>
NettyDemoServer:
import cn.test.demo.netty.handler.NettyDemoServerHandler; import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; 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.DelimiterBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; /** * Created by xiehua on 2018/2/08. */ public class NettyDemoServer { public void bind(int port) throws Exception{ 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 protected void initChannel(SocketChannel channel) throws Exception { ByteBuf buf = Unpooled.copiedBuffer("$".getBytes()); channel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024,buf)); channel.pipeline().addLast(new StringDecoder()); channel.pipeline().addLast(new NettyDemoServerHandler()); } }); ChannelFuture f = b.bind(port).sync(); f.channel().closeFuture().sync(); } finally { // 释放资源 bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; new NettyDemoServer().bind(port); } }
NettyDemoServerHandler:
import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** * Created by xiehua on 2018/2/08. */ public class NettyDemoServerHandler extends ChannelInboundHandlerAdapter{ @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { String body = (String) msg; System.out.println("The msg from client is : " + body); String response = "Welcome to netty.$"; ByteBuf buf = Unpooled.copiedBuffer(response.getBytes()); ctx.writeAndFlush(buf); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); // 出现异常 释放资源 ctx.close(); } }
NettyDemoClient:
import cn.test.demo.netty.handler.NettyDemoClientHandler; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; 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.NioSocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.string.StringDecoder; /** * Created by hua on 2018/2/08. */ public class NettyDemoClient { public void connect(int port, String host) throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group).channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel channel) throws Exception { ByteBuf buf = Unpooled.copiedBuffer("$".getBytes()); channel.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf)); channel.pipeline().addLast(new StringDecoder()); channel.pipeline().addLast(new NettyDemoClientHandler()); } }); ChannelFuture f = b.connect(host, port).sync(); f.channel().closeFuture().sync(); } finally { group.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; String host = "127.0.0.1"; new NettyDemoClient().connect(port, host); } }
NettyDemoClientHandler:
import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** * Created by hua on 2018/2/08. */ public class NettyDemoClientHandler extends ChannelInboundHandlerAdapter{ @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { String request = "Hello netty.$"; ByteBuf buf = Unpooled.copiedBuffer(request.getBytes()); ctx.writeAndFlush(buf); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { String response = (String) msg; System.out.println("The message from server is : " + response); } @Override public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { ctx.flush(); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } }
好了,这样一个简单的Netty小程序边写好了,现在分别启动服务端和客户端,看看运行结果吧:
客户端运行结果:
服务端: