1.认识netty
官方介绍:Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients
Netty 是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。
Netty是一个NIO客户端服务器框架,可以快速轻松地开发网络应用程序,例如协议服务器和客户端。它极大地简化和精简了 TCP 和 UDP 套接字服务器等网络编程。“快速简便”并不意味着最终的应用程序将遭受可维护性或性能问题的困扰。Netty 是根据从许多协议(例如 FTP、SMTP、HTTP 以及各种基于二进制和文本的遗留协议)的实现中获得的经验而精心设计的。结果,Netty 成功地找到了一种方法,可以在不妥协的情况下实现易于开发、性能、稳定性和灵活性。
2.netty api简单使用
ByteBuf byteBuf; @Before public void byteBufCommonTest(){ /**Bytebuf的多种分配方式*/ byteBuf= ByteBufAllocator.DEFAULT.buffer(8,12); ByteBufAllocator.DEFAULT.heapBuffer(8,12); ByteBufAllocator.DEFAULT.directBuffer(8,12); UnpooledByteBufAllocator.DEFAULT.heapBuffer(8,12); /**分配一个ByteBuf 初始大小为8,最大为12*/ } @Test public void mainTest(){ testReadAndWrite(); byteBuf.writeBytes(new byte[]{‘d‘, ‘d‘, ‘f‘, ‘g‘}); testReadAndWrite(); byteBuf.writeBytes(new byte[]{‘d‘, ‘d‘, ‘f‘, ‘g‘}); testReadAndWrite(); byteBuf.writeBytes(new byte[]{‘d‘, ‘d‘}); testReadAndWrite(); System.out.println(byteBuf); while (byteBuf.isReadable()) { System.out.println((char) byteBuf.readByte()); } } @Test public void testReadAndWrite(){ System.out.println("byteBuf.isWritable():"+byteBuf.isWritable()); System.out.println("byteBuf.writerIndex():"+byteBuf.writerIndex()); System.out.println("byteBuf.writableBytes():"+byteBuf.writableBytes()); System.out.println("byteBuf.isReadable():"+byteBuf.isReadable()); System.out.println("byteBuf.readerIndex():"+byteBuf.readerIndex()); System.out.println("byteBuf.readableBytes():"+byteBuf.readableBytes()); System.out.println("====================================="); }
测试mainTest(),输出如下,可以看出,当byteBuf中有数据时可以读取,而且,当写入时达到默认大小时,会进行扩展,到最大值,超出了最大值将报错!
byteBuf.isWritable():true byteBuf.writerIndex():0 byteBuf.writableBytes():8 byteBuf.isReadable():false byteBuf.readerIndex():0 byteBuf.readableBytes():0 ===================================== byteBuf.isWritable():true byteBuf.writerIndex():4 byteBuf.writableBytes():4 byteBuf.isReadable():true byteBuf.readerIndex():0 byteBuf.readableBytes():4 ===================================== byteBuf.isWritable():false byteBuf.writerIndex():8 byteBuf.writableBytes():0 byteBuf.isReadable():true byteBuf.readerIndex():0 byteBuf.readableBytes():8 ===================================== byteBuf.isWritable():true byteBuf.writerIndex():10 byteBuf.writableBytes():2 byteBuf.isReadable():true byteBuf.readerIndex():0 byteBuf.readableBytes():10 ===================================== PooledUnsafeDirectByteBuf(ridx: 0, widx: 10, cap: 12/12) d d f g d d f g d d
3.简单的netty交互
程序编写neety客户端:
@Test public void ClinetTest() throws Exception{ NioSocketChannel channel=new NioSocketChannel(); NioEventLoopGroup group=new NioEventLoopGroup(1); group.register(channel); ChannelFuture future=channel.connect(new InetSocketAddress("192.168.72.200",9999)); //future.sync(); ChannelFuture future1w=channel.writeAndFlush(Unpooled.copiedBuffer("sdfsdfsdf".getBytes())); //future1w.sync();/**意思是要等待future1w执行完成,其实就是将异步执行转换为同步执行*/ Thread.sleep(10000); }
执行之后结果显示:如果不使用future1w.sync()做同步处理,当方法中的程序执行完成之后,整个程序结束,客户端关闭,如果消息还未发送至服务端,将会停止,服务端从头到尾也没有接收到任何信息
4.双向交互
@Test public void doubleClientTest() throws Exception{ NioEventLoopGroup group=new NioEventLoopGroup(2); NioSocketChannel channel=new NioSocketChannel(); group.register(channel); ChannelFuture connectFuture=channel.connect(new InetSocketAddress("192.168.72.200",9999)); ChannelPipeline pipeline=channel.pipeline();/**获取通道*/ pipeline.addLast(new MyHandler()); ChannelFuture channelFuture=connectFuture.sync(); channelFuture.channel().closeFuture().sync();/**等待通道关闭*/ } class MyHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf byteBuf=(ByteBuf)msg; System.out.println(byteBuf.getCharSequence(0,byteBuf.readableBytes(), CharsetUtil.UTF_8)); ctx.writeAndFlush(byteBuf); } }
执行结果:
服务端发送一条消息,经过客户端会写,在服务端展示信息
5.服务端举例:
@Test public void doubleTClientTest() throws Exception{ NioEventLoopGroup group=new NioEventLoopGroup(2); ServerBootstrap bootstrap=new ServerBootstrap(); ChannelFuture future= bootstrap.group(group,group). channel(NioServerSocketChannel.class). childHandler(new ChannelInitializer<NioSocketChannel>() { @Override protected void initChannel(NioSocketChannel ch) throws Exception { ChannelPipeline pipeline= ch.pipeline(); pipeline.addLast(new MyHandler()); } }).bind("192.168.72.1",8080); future.sync().channel().closeFuture().sync(); } } class MyHandler extends ChannelInboundHandlerAdapter { @Override public void channelRegistered(ChannelHandlerContext ctx) throws Exception { System.out.println("regist:"+ctx.channel().remoteAddress()); } @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { ByteBuf byteBuf=(ByteBuf)msg; System.out.println(byteBuf.getCharSequence(0,byteBuf.readableBytes(), CharsetUtil.UTF_8)); ctx.writeAndFlush(byteBuf); } }