Netty 5用户指南
Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能、高可靠性的网络服务器和客户端程序。换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络应用程序,比如客户端和服务端的协议。Netty大大简化了网络程序的开发过程比如TCP和UDP的 Socket的开发。
"快速和简单"并不意味着应用程序会有难维护和性能低的问题,Netty是一个精心设计的框架,它从许多协议的实现中吸收了很多的经验比如FTP、SMTP、HTTP、许多二进制和基于文本的传统协议,Netty在不降低开发效率、性能、稳定性、灵活性情况下,成功地找到了解决方案。
Netty的核心组件包括:EventLoopGroup、ServerBootstrap、Handler等,其中像EventLoopGroup、Channel等都是可以灵活调配的。下面我们从代码示例开始我们的讲解。
- Bootstrap负责启动引导
- Buffer是Netty自己封装的缓存器
- Channel负责管理和建立连接
- Handler是责任链路模式中的处理者
- Util是Netty提供和使用到的一些工具
一、Netty Server
一个NettyServer程序主要由两部分组成:(1)BootsTrapping:配置服务器端基本信息;(2)ServerHandler:真正的业务逻辑处理。
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)
@Override
public 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;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new DiscardServer(port).run();
}
}
1、NioEventLoopGroup 是用来处理I/O操作的多线程事件循环器,Netty提供了许多不同的EventLoopGroup的实现用来处理不同传输协议。在这个例子中我们实现了一个服务端的应用,因此会有2个NioEventLoopGroup会被使用。第一个经常被叫做‘boss’,用来接收进来的连接。第二个经常被叫做‘worker’,用来处理已经被接收的连接,一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上。 如何知道多少个线程已经被使用,如何映射到已经创建的Channels上都需要依赖于EventLoopGroup的实现,并且可以通过构造函数来配置他们的关系;
2、ServerBootstrap 是一个启动NIO服务的辅助启动类。你可以在这个服务中直接使用Channel,但是这会是一个复杂的处理过程,在很多情况下你并不需要这样做;
3、这里我们指定使用NioServerSocketChannel类来举例说明一个新的Channel如何接收进来的连接;
4、这里的事件处理类经常会被用来处理一个最近的已经接收的Channel。ChannelInitializer是一个特殊的处理类,他的目的是帮助使用者配置一个新的Channel。也许你想通过增加一些处理类比如DiscardServerHandle来配置一个新的Channel或者其对应的ChannelPipeline来实现你的网络程序。当你的程序变的复杂时,可能你会增加更多的处理类到pipline上,然后提取这些匿名类到最顶层的类上。
5、可以设置这里指定的通道实现的配置参数。我们正在写一个TCP/IP的服务端,因此我们被允许设置socket的参数选项比如tcpNoDelay和keepAlive;
6、option()是提供给NioServerSocketChannel用来接收进来的连接。childOption()是提供给由父管道ServerChannel接收到的连接,在这个例子中也是NioServerSocketChannel。
ServerHandler配置如下:
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)
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) { // (2)
// Discard the received data silently.
((ByteBuf) msg).release(); // (3)
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
// Close the connection when an exception is raised.
cause.printStackTrace();
ctx.close();
}
1、chanelRead()事件处理方法。每当从客户端收到新的数据时,这个方法会在收到消息时被调用,这个例子中,收到的消息的类型是ByteBuf;其中ByteBuf是一个引用计数对象,这个对象必须显示地调用release()方法来释放;
2、 exceptionCaught()事件处理方法是当出现Throwable对象才会被调用,即当Netty由于IO错误或者处理器在处理事件时抛出的异常时。在大部分情况下,捕获的异常应该被记录下来并且把关联的channel给关闭掉。然而这个方法的处理方式会在遇到不同异常的情况下有不同的实现,比如你可能想在关闭连接之前发送一个错误码的响应消息。
二、Netty Client
public static void main(String[] args) throws Exception {
String host = args[0];
int port = Integer.parseInt(args[1]);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap(); // (1)
b.group(workerGroup); // (2)
b.channel(NioSocketChannel.class); // (3)
b.option(ChannelOption.SO_KEEPALIVE, true); // (4)
b.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new TimeClientHandler());
}
});
// Start the client.
ChannelFuture f = b.connect(host, port).sync(); // (5)
// Wait until the connection is closed.
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
}
}
}
2、如果你只指定了一个EventLoopGroup,那他就会即作为一个‘boss’线程,也会作为一个‘workder’线程,尽管客户端不需要使用到‘boss’线程;
3、代替NioServerSocketChannel的是NioSocketChannel,这个类在客户端channel被创建时使用;
4、不像在使用ServerBootstrap时需要用childOption()方法,因为客户端的SocketChannel没有父channel的概念;
5、用connect()方法代替了bind()方法;
@Override
public void channelActive(final ChannelHandlerContext ctx) { // (1)
final ByteBuf time = ctx.alloc().buffer(4); // (2)
time.writeInt((int) (System.currentTimeMillis() / 1000L + 2208988800L));
final ChannelFuture f = ctx.writeAndFlush(time); // (3)
f.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future) {
assert f == future;
ctx.close();
}
}); // (4)
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
Netty 5用户指南的更多相关文章
- netty用户指南
Netty用户指南 一.前言 1.问题 当今世界我们需要使用通用的软件或库与其他组件进行通信,例如使用HTTP客户端从服务器中获取信息,或通过网络服务调用一个远程的方法.然而通用的协议及其实现通常不具 ...
- 【翻译】Flume 1.8.0 User Guide(用户指南) source
翻译自官网flume1.8用户指南,原文地址:Flume 1.8.0 User Guide 篇幅限制,分为以下5篇: [翻译]Flume 1.8.0 User Guide(用户指南) [翻译]Flum ...
- dubbo用户指南
用户指南 入门 背景 需求 架构 用法 快速启动 服务提供者 服务消费者 依赖 必需依赖 缺省依赖 可选依赖 成熟度 功能成熟度 策略成熟度 配置 Xml配置 属性配置 注解配置 API配置 示例 启 ...
- dubbo用户指南-总结
dubbo用户指南-总结 入门 背景 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用 ...
- flume1.9 用户指南(中文版)
概述 Apache Flume是一个分布式,可靠且可用的系统,用于有效地从许多不同的source收集,聚合和移动大量日志数据到集中式数据存储. Apache Flume的使用不仅限于日志数据聚合.由于 ...
- Gradle用户指南(1)-Gradle安装
前置条件 Gradle 需要 Java JDK 或者 JRE,版本是 6 及以上.Gradle 将会装载自己的 Groovy 库,因此,Groovy 不需要被安装.任何存在的 Groovy 安装都会被 ...
- Gradle用户指南(章9:Groovy快速入门)
Gradle用户指南(章9:Groovy快速入门) 你可以使用groovy插件来构建groovy项目.这个插件继承了java插件的功能,且扩展了groovy编译.你的项目可以包含groovy代码.ja ...
- Gradle用户指南
下载安装gradle 2.1 下载地址:http://www.gradle.org/learn 安装先决条件:gradle安装需要1.6或者更高版本的jdk(jre)(可以使用java –versio ...
- scons用户指南翻译(附gcc/g++参数详解)
scons用户指南 翻译 http://blog.csdn.net/andyelvis/article/category/948141 官网文档 http://www.scons.org/docume ...
随机推荐
- hadoop2.2编程:使用MapReduce编程实例(转)
原文链接:http://www.cnblogs.com/xia520pi/archive/2012/06/04/2534533.html 从网上搜到的一篇hadoop的编程实例,对于初学者真是帮助太大 ...
- Linux Kernel ‘write_tag_3_packet()’函数本地基于堆的缓冲区溢出漏洞
漏洞名称: Linux Kernel ‘write_tag_3_packet()’函数本地基于堆的缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-067 发布时间: 2013-11-07 ...
- Java Socket 异常 Connection reset
最近使用Java做Socket客户端,与C的Socket服务端交互.遇到问题:现象是可以从服务端接受小数据,但是如果接受大数据,总是遇到Connection reset的异常:如果把服务端和客户端放到 ...
- HDU4725 The Shortest Path in Nya Graph dij
分析:对于每一层,原来n个点,然后扩展为原来的三倍,每一层扩展一个入点,一个出点,然后跑最短路 注:tmd我把一个n写成m了,然后wa了7次,我都要怀疑人生了 #include<cstdio&g ...
- 跟我学机器视觉-HALCON学习例程中文详解-开关引脚测量
跟我学机器视觉-HALCON学习例程中文详解-开关引脚测量 This example program demonstrates the basic usage of a measure object. ...
- 关于sharepoint事件接收器中properties.AfterProperties[""].Tostring()取值的问题。
这个这个属性是不能获取到中文的意思,他是获取AfterProperties的集合的值. string name=properties.AfterProperties["登录人"]. ...
- C(n,k)在n个不重复数中获得k个数
//比如在数组a[]={1,7,89,87} 中k=2的时候 组合为 C(4,2)=6 package 再次开始; import java.util.ArrayList; //本次实现的是在n个不重复 ...
- TCA9546A
The TCA9546A is a 4-channel, bidirectional translating switch for I 2 C buses that supports Standard ...
- 5 crucial optimizations for SSD usage in Ubuntu Linux
I bought my first SSD more than 5 years ago (late 2007), for my white MacBook Core2Duo 2.0 Ghz. It m ...
- hdu 1754 I Hate It (splay tree伸展树)
hdu 1754 I Hate It 其实我只是来存一下我的splay模板的..请大牛们多多指教 #include<stdio.h> #include<string.h> #i ...