首先,Netty启动使用的是bootstrap,通过ServerBootstrap启动服务端代码,需要四部:
第一步,绑定两个线程组分别用来处理客户端通道的accept和读写事件。
第二部,绑定服务端通道NioServerSocketChannel.
第三部,给读写事件的线程通道绑定handle去真正处理读写。
第四部,绑定监听。
下面我写下服务端代码:
package com.bstek.netty; import io.netty.bootstrap.ServerBootstrap; 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.string.StringEncoder; /** *@package com.bstek.netty *@File Title: NettyServer.java *@author beyond *@Company:bstek *@version 1.0 *@since:2017年12月23日 上午9:18:33 *@Description <-根据业务不同请修改-> */ public class NettyServer { public static void main(String[] args) throws InterruptedException { ServerBootstrap server= new ServerBootstrap(); // 1、绑定两个线程组分别用来处理客户端通道的accept和读写时间 // 2、绑定服务端通道NioServerSocketChannel // 3、给读写时间的线程通道绑定handle去真正处理读写 // 4、监听端口 EventLoopGroup parentGroup = new NioEventLoopGroup(); EventLoopGroup childGroup = new NioEventLoopGroup(); server.group(parentGroup , childGroup); server.channel(NioServerSocketChannel.class); server.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new SimpleServerHandler()); ch.pipeline().addLast(new StringEncoder()); } }); ChannelFuture future = server.bind(8080).sync(); future.channel().closeFuture().sync();//这是个阻塞 } } |
服务端处理读写的handle
package com.bstek.netty; import java.nio.charset.Charset; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** *@package com.bstek.netty *@File Title: SimpleServerHandler.java *@author beyond *@Company:bstek *@version 1.0 *@since:2017年12月23日 上午9:29:01 *@Description <-编写服务器接受,并返回-> */ public class SimpleServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if(msg instanceof ByteBuf){ System.out.println(((ByteBuf)msg).toString(Charset.defaultCharset())); } ctx.channel().writeAndFlush("is ok"); } } |
客户端调用,同样适用bootstrap启动,去掉server即可。
首先也是绑定线程组,即父线程组和子线程组
绑定通道
初始化NioSocketChannel
连接服务端端口
客户端调用的代码
package com.bstek.netty; import io.netty.bootstrap.Bootstrap; 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.NioSocketChannel; import io.netty.handler.codec.string.StringEncoder; /** *@package com.bstek.netty *@File Title: NettyClient.java *@author beyond *@Company:bstek *@version 1.0 *@since:2017年12月23日 上午9:43:28 *@Description <-根据业务不同请修改-> */ public class NettyClient { public static void main(String[] args) throws InterruptedException { Bootstrap client= new Bootstrap(); EventLoopGroup group= new NioEventLoopGroup(); //绑定线程组,处理读写和连接事件 client.group(group); client.channel(NioSocketChannel.class); //初始化NioSocketH client.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new SimpleClientHandler()); ch.pipeline().addLast(new StringEncoder()); } }); ChannelFuture future = client.connect("localhost",8080).sync(); future.channel().writeAndFlush("hello world !"); future.channel().closeFuture().sync(); System.out.println("客户端运行完毕"); } } |
处理类,handle
package com.bstek.netty; import java.nio.charset.Charset; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; /** *@package com.bstek.netty *@File Title: SimpleClientHandler.java *@author beyond *@Company:bstek *@version 1.0 *@since:2017年12月23日 上午9:49:19 *@Description <-读取服务端返回的内容-> */ public class SimpleClientHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //接受服务端传回来的值 if(msg instanceof ByteBuf){ System.out.println(((ByteBuf) msg).toString(Charset.defaultCharset())); } ctx.channel().close(); } } |
总结:
思考一个问题,什么是netty。
Netty是提供异步的,事件驱动的网络应用程序框架和工具,用以快速开发高性能,高可靠性的网络服务器和客户端程序。
再思考下,Netty有哪些特性。
设计
统一的api,适用于不同的协议。
基于灵活,可扩展的时间驱动模型。
高度可定制的线程模型。
可靠的无连接数据socket支持
(udp)。
性能
更好的吞吐量,低延迟
更省资源
尽量减少不必要的内存拷贝
安全
完整的ssl/tls和starttls的支持
能在google android与applet 的限制环境运行良好,
健壮性
不再因过快,过慢或超负载连接导致OutOfMemoryError
不再有在高速网络环境下Nio读写频率不一致的问题
易用性
完善的java doc 用户指南和样例
简洁简单
仅依赖与jdk1.5
谢谢
2017-12-23 23:56