一 初遇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快速入门相关推荐

  1. 分布式应用框架Akka快速入门

    转自:分布式应用框架Akka快速入门_jmppok的专栏-CSDN博客_akka 本文结合网上一些资料,对他们进行整理,摘选和翻译而成,对Akka进行简要的说明.引用资料在最后列出. 1.什么是Akk ...

  2. Netty快速入门与Reactor模式

    Netty概述 原生NIO存在的问题 NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.ServerSocketChannel.SocketChannel.ByteBuffer等 需要 ...

  3. Spring入门第一讲——Spring框架的快速入门

    Spring的概述 什么是Spring? 我们可以从度娘上看到这样有关Spring的介绍: 说得更加详细一点,Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架, ...

  4. Struts2入门第一讲——Struts2框架的快速入门

    Struts2框架的概述 Struts2是一种基于MVC模式的轻量级Web框架,它自问世以来,就受到了广大Web开发者的关注,并广泛应用于各种企业系统的开发中.目前掌握Struts2框架几乎成为Web ...

  5. go语言MVC框架beego快速入门

    beego快速入门 beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API.Web 及后端服务等各种应用,是一个 RESTful 的框架,主要设计灵感来源于 tornad ...

  6. php yii2框架教程,Yii2框架使用快速入门

    Yii 是一个通用的 Web 编程框架,即可以用于开发各种用 PHP 构建的 Web 应用. 因为基于组件的框架结构和设计精巧的缓存支持,它特别适合开发大型应用, 如门户网站.社区.内容管理系统(CM ...

  7. Shiro安全框架【快速入门】就这一篇!

    Shiro 简介 照例又去官网扒了扒介绍: Apache Shiro™ is a powerful and easy-to-use Java security framework that perfo ...

  8. python数据处理框架_python 最快 web 框架 Sanci 快速入门

    简介 Sanic 是一个和类Flask 的基于Python3.5+的web框架,它编写的代码速度特别快. 除了像Flask 以外,Sanic 还支持以异步请求的方式处理请求.这意味着你可以使用新的 a ...

  9. Python 什么是flask框架?快速入门

    一.Python flask框架 前言 1.Python 面向对象的高级编程语言,以其语法简单.免费开源.免编译扩展性高,同时也可以嵌入到C/C++程序和丰富的第三方库,Python运用到大数据分析. ...

最新文章

  1. CNN 分类古代陶器,表现超过考古专家,解决“考古学中的肮脏秘密”
  2. Python 工匠:在边界处思考
  3. 单帧风景照变延时摄影,分分钟搞定,还能有昼夜变化,这是来自日本的开源动画景观算法...
  4. greenplum gpfdist应用
  5. 【ES6(2015)】Map
  6. CentOs基础操作指令(用户管理、组管理)
  7. 反射(二) :整型数组能存字附---反射”暴力“超越数据类型的检测
  8. C语言学习笔记--数组指针和指针数组
  9. SpringBoot笔记7:使用JavaMail结合RabbitMQ发送邮件
  10. H5+CSS3面试题
  11. [Win10] 解决 Office 安装后图标空白的问题
  12. php下载微信服务器图片
  13. 分享解决jar包冲突问题的方法:(看了这个你就能解决所有包冲突问题!)
  14. 赞!走心推荐这几个 BAT 大佬的公众号
  15. Python 安装pyqt—tools失败,记录
  16. 快速排序算法原理 Quicksort —— 图解(精讲) JAVA
  17. 阿里云ECS服务器安装宝塔BT面板图文教程
  18. C++ 实时显示7z压缩与解压缩的进度
  19. 【线上分享】全球多媒体视频内容保护最佳实践
  20. 安卓自定义下拉列表样式_自定义下拉列表样式

热门文章

  1. linux df du命令
  2. USACO-Section1.5 Mother's Milk (深度优先搜索)
  3. Error: Could not find or load main class org.elasticsearch.tools.JavaVersionChecker
  4. 使用证书登陆Linux服务器
  5. UWP Acrylic Material
  6. Py与Py3的区别之输入input()函数
  7. 3.使用Selenium模拟浏览器抓取淘宝商品美食信息
  8. 如何把Python脚本导出为exe程序
  9. elipse安装php
  10. SharePoint 2010: 对于开发人员