Netty详细讲解
来源:互联网 发布:linux中安装anaconda 编辑:程序博客网 时间:2024/06/02 00:59
github代码地址:https://github.com/gudepeng/gdpNetty
本教程使用的Netty版本为4.1.15.Final
一、Netty详解
Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
也就是说,Netty 是一个基于NIO的客户、服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。
“快速”和“简单”并不用产生维护性或性能上的问题。Netty 是一个吸收了多种协议的实现经验,这些协议包括FTP,SMTP,HTTP,各种二进制,文本协议,并经过相当精心设计的项目,最终,Netty 成功的找到了一种方式,在保证易于开发的同时还保证了其应用的性能,稳定性和伸缩性。
(来源于百度百科)
二、服务端编写
2.1代码展示
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(); } }}
2.2详细讲解
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(); } }}
阅读全文
0 0
- Netty详细讲解
- netty 详细说明
- 详细讲解
- Netty学习(三)-Netty重要接口讲解
- Netty初学之一:简介-HellWord-讲解
- 手机视频格式详细讲解
- linux文件系统详细讲解
- jsessionid详细讲解
- 文件上传详细讲解
- 详细讲解Quartz.NET
- 详细讲解Quartz.NET
- Java HashMap详细讲解
- Struts配置文件详细讲解
- 详细讲解Quartz.NET
- 详细讲解Quartz.NET
- CString详细讲解
- window.event详细讲解
- 详细讲解Quartz.NET
- 动态添加和删除布局
- DrawerLayout中菜单栏和主界面点击失效的原因
- bootstrap-star-rating使用详解
- mongoDB基础使用(二)
- Android App Logging 组件客制化
- Netty详细讲解
- C++的基础知识(十)--deque
- toryboard (<UIStoryboard: 0x17406dc00>) doesn't contain a view controller with identifier 'UIViewCon
- svn
- 特征选择之方法概述
- 集群/分布式环境下5种session处理策略
- bzoj2243: [SDOI2011]染色(树链剖分+线段树)
- HTML5 文件域+FileReader 分段读取文件并上传到服务器
- 字符与字节有什么区别