github代码地址:https://github.com/gudepeng/gdpNettyjava
本教程使用的Netty版本为4.1.15.Finalgit
Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 能够确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty至关简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。
“快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸取了多种协议的实现经验,这些协议包括FTP,SMTP,HTTP,各类二进制,文本协议,并通过至关精心设计的项目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
github
(来源于百度百科)编程
public class NettyServer { public static void main(String[] args) { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup); b.channel(NioServerSocketChannel.class); b.childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline() // 以("\n")为结尾分割的 解码器 .addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())) .addLast(new StringDecoder()) .addLast(new StringEncoder()) .addLast(new SimpleChannelInboundHandler<String>() { @Override public void channelRead0(ChannelHandlerContext ctx, String s) throws Exception { // 收到消息直接打印输出 System.out.println(ctx.channel().remoteAddress() + "客戶端消息 :" + s); // 返回客户端消息 - 我已经接收到了你的消息 ctx.writeAndFlush("收到你的消息\n"); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println(ctx.channel().remoteAddress() + "客户端发来连接"); ctx.writeAndFlush("欢迎连接\n"); super.channelActive(ctx); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { System.out.println("发生错误"); cause.printStackTrace(); ctx.close(); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("服务端关闭"); super.channelInactive(ctx); } }); } }); b.option(ChannelOption.SO_BACKLOG, 1024); b.childOption(ChannelOption.SO_KEEPALIVE, true); // 服务器绑定端口监听 ChannelFuture f = b.bind(8099).sync(); // 监听服务器关闭监听 f.channel().closeFuture().sync(); } catch (Exception e) { e.printStackTrace(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
ChannelInitializer类中能够设置具体的任务链:
能够添加编码器解码器,监听器和处理器等。
能够添加多个SimpleChannelInboundHandler类的处理器。
若是须要继续执行下个处理器,须要在channelRead0方法中的fireChannelActive()方法
SimpleChannelInboundHandler类中定义处理类:
1.channelActive方法:客户端第一次连接时执行
2.channelRead0方法:客户端发来信息执行
3.channelInactive方法:服务端关闭时执行
4.exceptionCaught方法:发生异常时执行
public class NettyClient { public static void main(String[] args) throws InterruptedException { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group); b.channel(NioSocketChannel.class); b.option(ChannelOption.TCP_NODELAY, true); b.handler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline() // 以("\n")为结尾分割的 解码器 .addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())) .addLast(new StringDecoder()) .addLast(new StringEncoder()) .addLast(new SimpleChannelInboundHandler<String>() { @Override public void channelRead0(ChannelHandlerContext ctx, String s) throws Exception { // 收到消息直接打印输出 System.out.println("服务端消息 : " + s); } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("发起服务端连接"); super.channelActive(ctx); } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { System.out.println("客户端关闭"); super.channelInactive(ctx); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { System.out.println("发生错误"); cause.printStackTrace(); ctx.close(); } }); } }); // 链接服务端 Channel ch = b.connect("127.0.0.1", 8099).sync().channel(); // 控制台输入 BufferedReader in = new BufferedReader(new InputStreamReader( System.in)); for (;;) { String line = in.readLine(); if (line == null) { continue; } /* * 向服务端发送在控制台输入的文本 并用"\r\n"结尾 之因此用\r\n结尾 是由于咱们在handler中添加了 * DelimiterBasedFrameDecoder 帧解码。 * 这个解码器是一个根据\n符号位分隔符的解码器。因此每条消息的最后必须加上\n不然没法识别和解码 */ ch.writeAndFlush(line + "\n"); } } catch (Exception e) { e.printStackTrace(); } finally { group.shutdownGracefully(); } } }