网络应用框架Netty快速入门
一 初遇Netty
<font color="#33CC33" size="4"> Netty是什么?</font>
<font color="#6666CC">Netty 是一个提供 asynchronous event-driven (异步事件驱动)的网络应用框架,是一个用以快速开发高性能、可扩展协议的服务器和客户端。</font>
<font color="#33CC33" size="4"> Netty能做什么?</font>
<font color="#6666CC">Netty 是一个 NIO 客户端服务器框架,使用它可以快速简单地开发网络应用程序,比如服务器(HTTP服务器,FTP服务器,WebSocket服务器,Redis的Proxy服务器等等)和客户端的协议。Netty 大大简化了网络程序的开发过程比如 TCP 和 UDP 的 socket 服务的开发。</font>
<font color="#33CC33" size="4"> Netty为什么好?</font>
<font color="#6666CC">Netty是建立在NIO基础之上,Netty在NIO之上又提供了更高层次的抽象,使用它你可以更容易利用Java NIO提高服务端和客户端的性能。</font>
Netty的特性:
<font color="#99CCCC"> 1. 设计</font>
1.1 统一的API,适用于不同的协议(阻塞和非阻塞)1.2 基于可扩展和灵活的事件驱动模型1.3高度可定制的线程模型 - 单线程,一个或多个线程池,如SEDA1.4真正的无连接数据报套接字支持(自3.1以来)
<font color="#99CCCC">2. 性能</font>
2.1更好的吞吐量,低延迟2.2更省资源2.3尽量减少不必要的内存拷贝
<font color="#99CCCC">3. 安全</font>
完整的SSL / TLS和StartTLS协议的支持
<font color="#99CCCC">4. 易用性</font>
4.1 官方有详细的使用指南4.2 对环境要求很低
<font color="#33CC33" size="4"> NIO和IO的区别是什么?</font>
<font color="#99CCCC">1. 一个面向字节一个面向缓冲;</font>
IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方。此外,它不能前后移动流中的数据。如果需要前后移动从流中读取的数据,需要先将它缓存到一个缓冲区。 Java NIO的缓冲导向方法略有不同。数据读取到一个它稍后处理的缓冲区,需要时可在缓冲区中前后移动。这就增加了处理过程中的灵活性。但是,还需要检查是否该缓冲区中包含所有您需要处理的数据。而且,需确保当更多的数据读入缓冲区时,不要覆盖缓冲区里尚未处理的数据。
<font color="#99CCCC">2. NIO是非阻塞IO,IO是阻塞IO</font>
阻塞意味着当一个线程调用read() 或 write()时,该线程被阻塞,直到有一些数据被读取,或数据完全写入,该线程在此期间不能再干任何事情了。而非阻塞不会这样。
二 Netty使用
环境要求:
- JDK 7+
- Maven 3.2.x
- Netty 4.x
Maven依赖:
<dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.0.32.Final</version></dependency>
以下Netty examples来源: 官方文档
2.1 写个抛弃服务器
<font color="#99CCCC">DiscardServerHandler.java</font>
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;/*** handler 是由 Netty 生成用来处理 I/O 事件的。*/
public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)/*** 这里我们覆盖了 chanelRead() 事件处理方法。* 每当从客户端收到新的数据时,这个方法会在收到消息时被调用。*((ByteBuf) msg).release():丢弃数据*/@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)// 默默地丢弃收到的数据((ByteBuf) msg).release(); // (3)}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)// 当出现异常就关闭连接cause.printStackTrace();ctx.close();}
}
目前我们已经实现了 DISCARD 服务器的一半功能,剩下的需要编写一个 main() 方法来启动服务端的 DiscardServerHandler。
<font color="#99CCCC">DiscardServer.java</font>
import io.netty.bootstrap.ServerBootstrap;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.NioServerSocketChannel;/*** 启动服务端的 DiscardServerHandler*/
public class DiscardServer {private int port;public DiscardServer(int port) {this.port = port;}public void run() throws Exception {//在这个例子中我们实现了一个服务端的应用,因此会有2个 NioEventLoopGroup 会被使用。//第一个经常被叫做‘boss’,用来接收进来的连接。//第二个经常被叫做‘worker’,用来处理已经被接收的连接,一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上。EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup();try {//启动 NIO 服务的辅助启动类ServerBootstrap serverBootstrap = new ServerBootstrap(); //用于处理ServerChannel和Channel的所有事件和IO。serverBootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) // (3).childHandler(new ChannelInitializer<SocketChannel>() { // (4)@Overridepublic void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new DiscardServerHandler());}}).option(ChannelOption.SO_BACKLOG, 128) // (5).childOption(ChannelOption.SO_KEEPALIVE, true); // (6)// 绑定端口,开始接收进来的连接ChannelFuture f = serverBootstrap.bind(port).sync(); // (7)// 等待服务器 socket 关闭 。// 在这个例子中,这不会发生,但你可以优雅地关闭你的服务器。f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception {int port;if (args.length > 0) {port = Integer.parseInt(args[0]);} else {port = 8080;}new DiscardServer(port).run();}
}
2.2 查看收到的数据
我们刚刚已经编写出我们第一个服务端,我们需要测试一下他是否真的可以运行。最简单的测试方法是用 telnet 命令。例如,你可以在命令行上输入telnet localhost 8080 或者其他类型参数。
然而我们能说这个服务端是正常运行了吗?事实上我们也不知道,因为他是一个 discard 服务,你根本不可能得到任何的响应。为了证明他仍然是在正常工作的,让我们修改服务端的程序来打印出他到底接收到了什么。
我们已经知道 channelRead() 方法是在数据被接收的时候调用。让我们放一些代码到 DiscardServerHandler 类的 channelRead() 方法。
<font color="#99CCCC">修改DiscardServerHandler类的channelRead(ChannelHandlerContext ctx, Object msg)方法如下:</font>
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {ByteBuf in = (ByteBuf) msg;try {while (in.isReadable()) { // (1)System.out.print((char) in.readByte());System.out.flush();}} finally {ReferenceCountUtil.release(msg); // (2)}
}
再次验证,cmd下输入:telnet localhost 8080。你将会看到服务端打印出了他所接收到的消息。
如下:
你在dos界面输入的消息会被显示出来
2.3 写个应答服务器
到目前为止,我们虽然接收到了数据,但没有做任何的响应。然而一个服务端通常会对一个请求作出响应。让我们学习怎样在 ECHO 协议的实现下编写一个响应消息给客户端,这个协议针对任何接收的数据都会返回一个响应。
和 discard server 唯一不同的是把在此之前我们实现的 channelRead() 方法,返回所有的数据替代打印接收数据到控制台上的逻辑。因此,需要把 channelRead() 方法修改如下:
@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {ctx.write(msg); ctx.flush(); }
再次验证,cmd下输入:telnet localhost 8080。你会看到服务端会发回一个你已经发送的消息。
如下:
下一篇我们会学习如何用Netty实现聊天功能。
欢迎关注我的微信公众号:"Java 面试通关手册"(坚持原创,分享美文,分享各种Java学习资源,面试题,以及企业级Java实战项目回复关键字免费领取):
网络应用框架Netty快速入门相关推荐
- 分布式应用框架Akka快速入门
转自:分布式应用框架Akka快速入门_jmppok的专栏-CSDN博客_akka 本文结合网上一些资料,对他们进行整理,摘选和翻译而成,对Akka进行简要的说明.引用资料在最后列出. 1.什么是Akk ...
- Netty快速入门与Reactor模式
Netty概述 原生NIO存在的问题 NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.ServerSocketChannel.SocketChannel.ByteBuffer等 需要 ...
- Spring入门第一讲——Spring框架的快速入门
Spring的概述 什么是Spring? 我们可以从度娘上看到这样有关Spring的介绍: 说得更加详细一点,Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架, ...
- Struts2入门第一讲——Struts2框架的快速入门
Struts2框架的概述 Struts2是一种基于MVC模式的轻量级Web框架,它自问世以来,就受到了广大Web开发者的关注,并广泛应用于各种企业系统的开发中.目前掌握Struts2框架几乎成为Web ...
- go语言MVC框架beego快速入门
beego快速入门 beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API.Web 及后端服务等各种应用,是一个 RESTful 的框架,主要设计灵感来源于 tornad ...
- php yii2框架教程,Yii2框架使用快速入门
Yii 是一个通用的 Web 编程框架,即可以用于开发各种用 PHP 构建的 Web 应用. 因为基于组件的框架结构和设计精巧的缓存支持,它特别适合开发大型应用, 如门户网站.社区.内容管理系统(CM ...
- Shiro安全框架【快速入门】就这一篇!
Shiro 简介 照例又去官网扒了扒介绍: Apache Shiro™ is a powerful and easy-to-use Java security framework that perfo ...
- python数据处理框架_python 最快 web 框架 Sanci 快速入门
简介 Sanic 是一个和类Flask 的基于Python3.5+的web框架,它编写的代码速度特别快. 除了像Flask 以外,Sanic 还支持以异步请求的方式处理请求.这意味着你可以使用新的 a ...
- Python 什么是flask框架?快速入门
一.Python flask框架 前言 1.Python 面向对象的高级编程语言,以其语法简单.免费开源.免编译扩展性高,同时也可以嵌入到C/C++程序和丰富的第三方库,Python运用到大数据分析. ...
最新文章
- CNN 分类古代陶器,表现超过考古专家,解决“考古学中的肮脏秘密”
- Python 工匠:在边界处思考
- 单帧风景照变延时摄影,分分钟搞定,还能有昼夜变化,这是来自日本的开源动画景观算法...
- greenplum gpfdist应用
- 【ES6(2015)】Map
- CentOs基础操作指令(用户管理、组管理)
- 反射(二) :整型数组能存字附---反射”暴力“超越数据类型的检测
- C语言学习笔记--数组指针和指针数组
- SpringBoot笔记7:使用JavaMail结合RabbitMQ发送邮件
- H5+CSS3面试题
- [Win10] 解决 Office 安装后图标空白的问题
- php下载微信服务器图片
- 分享解决jar包冲突问题的方法:(看了这个你就能解决所有包冲突问题!)
- 赞!走心推荐这几个 BAT 大佬的公众号
- Python 安装pyqt—tools失败,记录
- 快速排序算法原理 Quicksort —— 图解(精讲) JAVA
- 阿里云ECS服务器安装宝塔BT面板图文教程
- C++ 实时显示7z压缩与解压缩的进度
- 【线上分享】全球多媒体视频内容保护最佳实践
- 安卓自定义下拉列表样式_自定义下拉列表样式
热门文章
- linux df du命令
- USACO-Section1.5 Mother's Milk (深度优先搜索)
- Error: Could not find or load main class org.elasticsearch.tools.JavaVersionChecker
- 使用证书登陆Linux服务器
- UWP Acrylic Material
- Py与Py3的区别之输入input()函数
- 3.使用Selenium模拟浏览器抓取淘宝商品美食信息
- 如何把Python脚本导出为exe程序
- elipse安装php
- SharePoint 2010: 对于开发人员