Netty简单样例分析[转]
转自:http://linugb118.blog.51cto.com/272628/420738
Netty 是JBoss旗下的io传输的框架,他利用java里面的nio来实现高效,稳定的io传输。
作为io传输,就会有client和server,下面我们看看用netty怎样写client和server
Client:
需要做的事情:
1.配置client启动类
ClientBootstrap bootstrap = new ClientBootstrap(..)
2.根据不同的协议或者模式为client启动类设置pipelineFactory。
这里telnet pipline Factory 在netty中已经存在,所有直接用
bootstrap.setPipelineFactory(new TelnetClientPipelineFactory());
也可以自己定义
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(
new DiscardClientHandler(firstMessageSize));
}
});
这里DiscardClientHandler 就是自己定义的handler,他需要
public class DiscardServerHandler extends SimpleChannelUpstreamHandler
继承SimpleChannelUpstreamHandler 来实现自己的handler。这里DiscardClientHandler
是处理自己的client端的channel,他的
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
// Server is supposed to send nothing. Therefore, do nothing.
}
可以看到Discard client不需要接受任何信息
3.连接server
ChannelFuture future = bootstrap.connect(new InetSocketAddress(host, port));
这里解释一下channelFuture:
在Netty中所有的io操作都是异步的,这也就是意味任何io访问,那么就立即返回处理,并且不能确保
返回的数据全部完成。因此就出现了channelFuture,channelFuture在传输数据时候包括数据和状态两个
部分。他只有Uncompleted和Completed
* +---------------------------+
* | Completed successfully |
* +---------------------------+
* +----> isDone() = <b>true</b> |
* +--------------------------+ | | isSuccess() = <b>true</b> |
* | Uncompleted | | +===========================+
* +--------------------------+ | | Completed with failure |
* | isDone() = <b>false</b> | | +---------------------------+
* | isSuccess() = false |----+----> isDone() = <b>true</b> |
* | isCancelled() = false | | | getCause() = <b>non-null</b> |
* | getCause() = null | | +===========================+
* +--------------------------+ | | Completed by cancellation |
* | +---------------------------+
* +----> isDone() = <b>true</b> |
* | isCancelled() = <b>true</b> |
* +---------------------------+
既然netty io是异步的,那么如何知道channel传送完成有两种方式,一种添加监听器
addListener(ChannelFutureListener) 还有一种直接调用await()方法,这两种方式
有下面的区别
监听器:是以事件模式的,因此代码就需要用事件模式的样式去写,相当复杂,但他是non-blocking模式的
性能方面要比await方法好,而且不会产生死锁情况
await(): 直接方法调用,使用简单,但是他是blocking模式,性能方面要弱而且会产生死锁情况
不要在ChannelHandler 里面调用await(),这是因为通常在channelHandler里的event method是被i/o线程调用的
(除非ChannelPipeline里面有个ExecutionHandler),那么如果这个时候用await就容易产生死锁。
错误样例:
// BAD - NEVER DO THIS
* {@code @Override}
* public void messageReceived({@link ChannelHandlerContext} ctx, {@link MessageEvent} e) {
* if (e.getMessage() instanceof GoodByeMessage) {
* {@link ChannelFuture} future = e.getChannel().close();
* future.awaitUninterruptibly();
* // Perform post-closure operation
* // ...
* }
* }
*
正确样例:
* // GOOD
* {@code @Override}
* public void messageReceived({@link ChannelHandlerContext} ctx, {@link MessageEvent} e) {
* if (e.getMessage() instanceof GoodByeMessage) {
* {@link ChannelFuture} future = e.getChannel().close();
* future.addListener(new {@link ChannelFutureListener}() {
* public void operationComplete({@link ChannelFuture} future) {
* // Perform post-closure operation
* // ...
* }
* });
* }
* }
虽然await调用比较危险,但是你确保不是在一个i/o 线程中调用该方法,毕竟await方法还是很简洁方便的,如果
调用该方法是在一个i/o 线程,那么就会抛出 IllegalStateException
await的timeout和i/o timeout区别
需要注意的是这两个timeout是不一样的, #await(long),#await(long, TimeUnit), #awaitUninterruptibly(long),
#awaitUninterruptibly(long, TimeUnit) 这里面的timeout也i/o timeout 没有任何关系,如果io timeout,那么
channelFuture 将被标记为completed with failure,而await的timeout 与future完全没有关系,只是await动作的
timeout。
错误代码
* // BAD - NEVER DO THIS
* {@link ClientBootstrap} b = ...;
* {@link ChannelFuture} f = b.connect(...);
* f.awaitUninterruptibly(10, TimeUnit.SECONDS);
* if (f.isCancelled()) {
* // Connection attempt cancelled by user
* } else if (!f.isSuccess()) {
* // You might get a NullPointerException here because the future
* // might not be completed yet.
* f.getCause().printStackTrace();
* } else {
* // Connection established successfully
* }
*
正确代码
* // GOOD
* {@link ClientBootstrap} b = ...;
* // Configure the connect timeout option.
* <b>b.setOption("connectTimeoutMillis", 10000);</b>
* {@link ChannelFuture} f = b.connect(...);
* f.awaitUninterruptibly();
*
* // Now we are sure the future is completed.
* assert f.isDone();
*
* if (f.isCancelled()) {
* // Connection attempt cancelled by user
* } else if (!f.isSuccess()) {
* f.getCause().printStackTrace();
* } else {
* // Connection established successfully
* }
4.等待或监听数据全部完成
如: future.getChannel().getCloseFuture().awaitUninterruptibly();
5.释放连接等资源
bootstrap.releaseExternalResources();
Server:
1.配置server
ServerBootstrap bootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
2.设置pipeFactory
bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() throws Exception {
return Channels.pipeline(new EchoServerHandler());
}
});
或者
bootstrap.setPipelineFactory(new HttpServerPipelineFactory());
3.绑定sever端端口
bootstrap.bind(new InetSocketAddress(8080));
转载于:https://www.cnblogs.com/york-hust/archive/2012/03/30/2424743.html
Netty简单样例分析[转]相关推荐
- Netty 简单样例分析(io传输的框架)
http://linugb118.blog.51cto.com/272628/420738 messageReceived(ChannelHandlerContext ctx, MessageEven ...
- 斗地主AI算法——第十六章の样例分析
上一章,我们已经完成了测试模块的开发.至此我们已经可以进行整体测试了.本章主要内容就是对随机生成的对局情况进行简单的分析. 实际上整个开发过程绝大部分时间都是用在样例分析上,通过样例给出的返回操作分析 ...
- [LoadRunner]LR性能测试结果样例分析
LR性能测试结果样例分析 测试结果分析 LoadRunner性能测试结果分析是个复杂的过程,通常可以从结果摘要.并发数.平均事务响应时间.每秒点击数.业务成功率.系统资源.网页细分图.Web服务器资源 ...
- 关于谷歌浏览器主页被篡改无法修正的样例分析与解决方案
关于谷歌浏览器主页被篡改无法修正的样例分析与解决方案 首先写在前面,浏览器被修改主页的情况很多,此次分析的仅为一个样例且给出解决的方法.本文主要提供自身经历和解决的思路,因为水平有限,无法给出专业化的 ...
- JDBC 连接Hive 简单样例(开启Kerberos)
今天在移动的云平台上通过jdbc连接hive,发现云平台使用了 kerberos的认证.与宁波实验环境不同. 发现一文解决了问题,转载如下: 原文地址:http://blog.csdn.net/zen ...
- php session 反序列化,PHP SESSION反序列化本地样例分析
PHP SESSION反序列化本地样例分析 0X00漏洞原因 主要原因是: ini_set('session.serialize_handler', 'php_serialize'); ini_set ...
- 重要性采样(Importance Sampling)简介和简单样例实现
重要性采样(Importance Sampling)简介和简单样例实现 在渲染领域,重要性采样这个术语是很常见的,但它究竟是什么呢?我们首先考虑这样的一种情况: 如果场景里有一点P,我们想计算P点的最 ...
- C语言单元测试之安装gtest教程及一个简单样例
准备工作 安装包:gtest1.7.0版本(最新的1.8.0版本一直安装失败,1.7.0版本一次成功) 安装链接:百度网盘 https://pan.baidu.com/s/1mDy9sB3sBIMei ...
- K8S Yaml 详细说明及简单样例
一.K8S Yaml 配置文件主要分为基本标签.元数据标签.资源内容 3 个部分 基本标签 apiVersion: v1 #必选,版本号,例如v1 kind: Pod #必选,Pod 元数据标签 me ...
最新文章
- 悲催的IE6,悲催的壳浏览器,悲催的搜狗,悲催的360
- MapReduce编程实战之“I/O”
- AWS的EC2上构建一个爬虫
- OpenCV定制和调试检测系统
- NK3C系统中ID的汉语名称
- [系统安全] 十.Windows漏洞利用之SMBv3服务远程代码执行漏洞(CVE-2020-0796)及防御详解
- Shell脚本中$0、$?、$!、$$、$*、$#、$@
- linux手机刷机包制作工具_ROM制作工具官方下载|ROM制作工具下载 v1.0.0.59 官方版 - 绿点软件站...
- Javascript 自定义输出
- 怎样写一个具有异步交互的React组件的单元测试
- [包计划] create-react-app
- laravel框架使用datatables
- 数学建模——更新1——excel箱线图
- 2012年九月六号阿里巴巴面试
- ImportError: CuPy is not correctly installed解决方法
- (转)Linux——pv、vg和lv的概念
- 粘包现象以及如何处理粘包
- 网站突然服务器到期,网站云服务器到期释放
- 正则表达式验证中文或者英文
- ocr文字识别软件安卓
热门文章
- 运维小白死磕的专业术语,你真的理解透了吗?
- 保护公民信息安全 中国在行动
- Spark入门(Python版)
- 网站中被误解的用户体验设计
- 计算机程序的构造和解释1构造过程抽象1.2过程与它们所产生的计算
- 新奇漂亮的Ajax/CSS表格设计汇集
- 人工鱼群算法python_人工鱼群算法简介及应用
- 小米8ios图标包下载_小米手机中这么实用的隐藏功能,知道的人居然那么少?真可惜...
- 国庆快乐,送3本Python书
- The package lists or status file could not be parsed or opened.