官网:https://netty.io/

以下内容大部分来自Netty官网内容

一、现有问题

现在我们使用通用应用程序或库来彼此通信。例如,我们经常使用HTTP客户端库从web服务器检索信息,并通过web服务调用远程过程调用。然而,一个通用协议或它的实现有时并不能很好地扩展。这就像我们没有使用通用的HTTP服务器来交换巨大的文件、电子邮件消息和接近实时的消息(如财务信息和多人游戏数据)。需要的是一个高度优化的协议实现,专门用于特定的目的。例如,您可能想实现一个针对基于ajax的聊天应用程序、媒体流或大型文件传输进行优化的HTTP服务器。您甚至可能想设计和实现一个全新的协议,它可以根据您的需要进行精确定制。另一种不可避免的情况是,您必须处理遗留的专有协议,以确保与旧系统的互操作性。在这种情况下,重要的是在不牺牲应用程序的稳定性和性能的情况下,我们可以多快地实现该协议。

二、解决方案

Netty项目致力于提供一个异步事件驱动的网络应用框架和工具,用于快速开发可维护的高性能和高可伸缩性协议服务器和客户端。

换句话说,Netty是一个NIO客户端服务器框架,它支持快速而简单地开发网络应用程序,如协议服务器和客户端。它极大地简化和简化了网络编程,如TCP和UDP套接字服务器开发。

“快速和简单”并不意味着结果应用程序将受到可维护性或性能问题的影响。Netty是经过精心设计的,从许多协议(如FTP、SMTP、HTTP和各种基于二进制和文本的遗留协议)的实现中吸取了经验。因此,Netty成功地找到了一种方法,可以在不妥协的情况下实现开发的易用性、性能、稳定性和灵活性。

有些用户可能已经发现了其他声称具有相同优势的网络应用程序框架,您可能想知道是什么使Netty与它们如此不同。答案是它所建立的哲学。Netty从一开始就为您提供API和实现方面最舒适的体验。这不是一些有形的东西,但你会意识到,这种哲学将使你的生活更容易,当你阅读本指南和玩Netty。

三、编写一个丢弃服务器

世界上最简单的协议不是“你好,世界!”但丢弃。它是一种丢弃任何接收到的数据而不进行任何响应的协议。

要实现丢弃协议,您需要做的唯一一件事就是忽略所有接收到的数据。让我们直接从处理程序实现开始,它处理Netty生成的I/O事件。

package io.netty.example.discard;import io.netty.buffer.ByteBuf;import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;/*** Handles a server-side channel.*/
public class DiscardServerHandler extends ChannelInboundHandlerAdapter { // (1)@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)// Discard the received data silently.((ByteBuf) msg).release(); // (3)}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)// Close the connection when an exception is raised.cause.printStackTrace();ctx.close();}
}

实现丢弃服务服务器:

package io.netty.example.discard;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;/*** Discards any incoming data.*/
public class DiscardServer {private int port;public DiscardServer(int port) {this.port = port;}public void run() throws Exception {EventLoopGroup bossGroup = new NioEventLoopGroup(); // (1)EventLoopGroup workerGroup = new NioEventLoopGroup();try {ServerBootstrap b = new ServerBootstrap(); // (2)b.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)// Bind and start to accept incoming connections.ChannelFuture f = b.bind(port).sync(); // (7)// Wait until the server socket is closed.// In this example, this does not happen, but you can do that to gracefully// shut down your server.f.channel().closeFuture().sync();} finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}}public static void main(String[] args) throws Exception {int port = 8080;if (args.length > 0) {port = Integer.parseInt(args[0]);}new DiscardServer(port).run();}
}

上述代码中数字分别代表以下内容:

1.NioEventLoopGroup是一个处理I/O操作的多线程事件循环。Netty为不同类型的传输提供了各种EventLoopGroup实现。在本例中,我们将实现一个服务器端应用程序,因此将使用两个NioEventLoopGroup。第一个,通常称为“boss”,接受一个传入连接。第二个,通常称为“worker”,在老板接受连接并向worker注册已接受的连接后,处理已接受连接的流量。使用多少线程以及如何将它们映射到创建的通道取决于EventLoopGroup实现,甚至可以通过构造函数进行配置。

2.ServerBootstrap是一个设置服务器的助手类。您可以直接使用通道设置服务器。但是,请注意,这是一个乏味的过程,而且在大多数情况下不需要这样做。

3.这里,我们指定使用NioServerSocketChannel类,该类用于实例化一个新通道以接受传入连接。

4.这里指定的处理程序将始终由新接受的通道进行评估。ChannelInitializer是一个特殊的处理程序,用于帮助用户配置新通道。您很可能希望通过添加一些处理程序(如DiscardServerHandler)来配置新通道的ChannelPipeline,以实现网络应用程序。随着应用程序变得越来越复杂,您可能会向管道中添加更多的处理程序,并最终将这个匿名类提取到一个顶级类中。

5.您还可以设置特定于通道实现的参数。我们正在编写一个TCP/IP服务器,因此允许设置套接字选项,如tcpNoDelay和keepAlive。请参考ChannelOption的apidocs和特定的ChannelConfig实现,以获得有关受支持的ChannelOptions的概述。

6.您注意到option()和childOption()了吗?option()用于接受传入连接的NioServerSocketChannel。childOption()用于父服务器通道(在本例中为NioServerSocketChannel)接受的通道。

7.我们现在准备走了。剩下的工作就是绑定到端口并启动服务器。在这里,我们绑定到机器中所有nic(网络接口卡)的端口8080。现在可以任意多次调用bind()方法(使用不同的绑定地址)。

查看接收到的数据

@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)}
}

1、他的低效循环实际上可以简化为:System.out.println(in.toString(io.netty.uti.charsetutil.us_ascii))

2、也可以在这里直接使用in.release()。

编写回显服务器

到目前为止,我们一直在使用数据而没有响应。然而,服务器通常应该响应请求。让我们学习如何通过实现ECHO协议向客户端编写响应消息,接收到的任何数据都会被发回。与我们在前几节中实现的丢弃服务器的惟一区别是,它将发送回接收到的数据,而不是将接收到的数据打印到控制台。因此,再次修改channelRead()方法就足够了:

 @Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) {ctx.write(msg); //Read完直接写给客户端 (1)ctx.flush(); // (2)可直接使用ctx.writeAndFlush(msg)}

1、ChannelHandlerContext对象提供各种操作,使您能够触发各种I/O事件和操作。在这里,我们调用write(Object)来逐字写入接收到的消息。请注意,我们没有像在丢弃示例中那样释放接收到的消息。这是因为Netty在将其写入网络时为您释放了它。

2、write(Object)不会将消息写入网络。它在内部进行缓冲,然后通过ctx.flush()将其刷新到连接上。或者,为了简洁,您可以调用ctx.writeAndFlush(msg)。

待续。。

Netty介绍 与第一个Netty实例相关推荐

  1. 《Netty In Action》第二章:第一个Netty程序

    2019独角兽企业重金招聘Python工程师标准>>> 源码地址: GitHub 2.3 编写一个应答服务器 写一个Netty服务器主要由两部分组成: 配置服务器功能,如线程.端口 ...

  2. 尚硅谷的Netty介绍(一)

    原文转载:Netty介绍及NIO详解_dzyls的笔记-CSDN博客 目录 Netty的介绍 netty概念 名词概念 netty应用场景 I/O模型基本说明 I/O模型基本说明 Java共支持的3种 ...

  3. Netty 系列一(核心组件和实例).

    一.概念 早期的 Java API 只支持由本地系统套接字库提供所谓的阻塞函数来支持网络编程.由于是阻塞 I/O ,要管理多个并发客户端,需要为每个新的客户端Socket 创建一个 Thread .这 ...

  4. 第一个Netty应用

    本文来做一个Netty的入门程序,即Netty的hello word入门级程序 文章目录 概述 导入Netty依赖 服务端 创建服务端 自定义服务端 ChannelHandler 处理消息 客户端 创 ...

  5. Netty介绍与实战(三)之粘包拆包

    一.传统NIO架构 step1. 我们传统的nio架构已经解决了多路复用,零拷贝等问题,已经十分优秀了,那为什么我们现在Netty如此火热呢? 1) 首先他使用简单,基本上都是模板化,我们可以更专注业 ...

  6. 一起来分解一个Netty应用

    ​前言 前面几篇博客主要介绍到了NIO针对网络IO场景相比较传统的Socket通信的优势,以及NIO在应用过程中线程模型的演化.从这篇博客开始我们一起来学习一个基于NIO实现的框架Netty,这是一个 ...

  7. Netty介绍及实战(二)之IO与NIO和多路复用与零拷贝

    Netty介绍及实战(一) 一.Netty到底是什么?什么是多路复用?什么叫做零拷贝? Netty是一个NIO客户端服务器框架,可以快速.轻松地开发协议服务器和客户端等网络应用程序.它极大地简化和简化 ...

  8. netty 远程主机强迫关闭了一个现有的连接_死磕netty系列《一、netty基础概念》...

    1. Channel Channel代表了netty对网络连接的抽象,Channel是线程安全的,它提供了一些重要信息,比如当前网络连接的状态,远程的主机连接地址和本地的连接地址, 我们可以通过 Ch ...

  9. 1、张龙netty学习 第一个netty服务端

    张龙netty学习 第一个netty服务端 public class TestServer {public static void main(String[] args) throws Excepti ...

最新文章

  1. java lombok 视频_Java开发神器Lombok使用详解
  2. php 两次post,ajax跨域往php程序post数据时,php程序总是执行两次的解决办法
  3. 数据结构——字符串(未完)
  4. python import
  5. CF700E-Cool Slogans【SAM,线段树合并,dp】
  6. 初步学习nodejs,业余用node写个一个自动创建目录和文件的小脚本,希望对需要的人有所帮助...
  7. 古老的window程序设计
  8. aspose 转pdf表格大小乱了_关于Aspose.Words转PDF简体中文排版问题申明
  9. 十大品牌去除甲醛净化器 哪个品牌好
  10. 第二十九节 MT-iBeacon基站关于LightBlue软件的使用
  11. 【转】密码破解全能工具:Hashcat密码破解攻略
  12. windows 系统 system 进程占用80端口
  13. python樱桃小丸子_appium+python自动化启动app
  14. JQuery插件validate的Remote使用
  15. 如何将Excel一页转PDF变多页?好用的PDF转换工具推荐
  16. Vasya the Hipster
  17. SCRATCH编程与科学——简单电路
  18. 成都中医药大学计算机基础试题,成都中医药大学2016年春季学期期末考试.计算机基础试卷-成教(答案~)分析总结.doc...
  19. ES 排序,相关度和热度之间的平衡
  20. 霍夫曼树(赫夫曼树、哈夫曼树)

热门文章

  1. ABAP中操作回车、换行、回车加换行、的方案
  2. 【MM】采购退货的处理办法
  3. 爱优腾芒“跑马圈地”,AI广告营销能拯救“盈利难”的视频平台吗?
  4. 从烤箱到蒸烤箱、到蒸烤箱集成灶,功能做加法,价格做乘法
  5. 主业失利,跨界捞金,飞科的算盘能如意吗?
  6. mysql安装 linux 5.6,Linux安装MySql5.6版详细教程
  7. oracle管理用户安全,oracle中管理用户的安全
  8. SQL语言之DQL语言学习(一) 基础查询
  9. Java爬虫技术(一)普通网站爬取图片
  10. CTF-杂项16进制字符串类型的题目