- 浏览: 2652325 次
- 来自: 杭州
文章分类
- 全部博客 (1188)
- webwork (4)
- 网摘 (18)
- java (103)
- hibernate (1)
- Linux (85)
- 职业发展 (1)
- activeMQ (2)
- netty (14)
- svn (1)
- webx3 (12)
- mysql (81)
- css (1)
- HTML (6)
- apache (3)
- 测试 (2)
- javascript (1)
- 储存 (1)
- jvm (5)
- code (13)
- 多线程 (12)
- Spring (18)
- webxs (2)
- python (119)
- duitang (0)
- mongo (3)
- nosql (4)
- tomcat (4)
- memcached (20)
- 算法 (28)
- django (28)
- shell (1)
- 工作总结 (5)
- solr (42)
- beansdb (6)
- nginx (3)
- 性能 (30)
- 数据推荐 (1)
- maven (8)
- tonado (1)
- uwsgi (5)
- hessian (4)
- ibatis (3)
- Security (2)
- HTPP (1)
- gevent (6)
- 读书笔记 (1)
- Maxent (2)
- mogo (0)
- thread (3)
- 架构 (5)
- NIO (5)
- 正则 (1)
- lucene (5)
- feed (4)
- redis (17)
- TCP (6)
- test (0)
- python,code (1)
- PIL (3)
- guava (2)
- jython (4)
- httpclient (2)
- cache (3)
- signal (1)
- dubbo (7)
- HTTP (4)
- json (3)
- java socket (1)
- io (2)
- socket (22)
- hash (2)
- Cassandra (1)
- 分布式文件系统 (5)
- Dynamo (2)
- gc (8)
- scp (1)
- rsync (1)
- mecached (0)
- mongoDB (29)
- Thrift (1)
- scribe (2)
- 服务化 (3)
- 问题 (83)
- mat (1)
- classloader (2)
- javaBean (1)
- 文档集合 (27)
- 消息队列 (3)
- nginx,文档集合 (1)
- dboss (12)
- libevent (1)
- 读书 (0)
- 数学 (3)
- 流程 (0)
- HBase (34)
- 自动化测试 (1)
- ubuntu (2)
- 并发 (1)
- sping (1)
- 图形 (1)
- freemarker (1)
- jdbc (3)
- dbcp (0)
- sharding (1)
- 性能测试 (1)
- 设计模式 (2)
- unicode (1)
- OceanBase (3)
- jmagick (1)
- gunicorn (1)
- url (1)
- form (1)
- 安全 (2)
- nlp (8)
- libmemcached (1)
- 规则引擎 (1)
- awk (2)
- 服务器 (1)
- snmpd (1)
- btrace (1)
- 代码 (1)
- cygwin (1)
- mahout (3)
- 电子书 (1)
- 机器学习 (5)
- 数据挖掘 (1)
- nltk (6)
- pool (1)
- log4j (2)
- 总结 (11)
- c++ (1)
- java源代码 (1)
- ocr (1)
- 基础算法 (3)
- SA (1)
- 笔记 (1)
- ml (4)
- zokeeper (0)
- jms (1)
- zookeeper (5)
- zkclient (1)
- hadoop (13)
- mq (2)
- git (9)
- 问题,io (1)
- storm (11)
- zk (1)
- 性能优化 (2)
- example (1)
- tmux (1)
- 环境 (2)
- kyro (1)
- 日志系统 (3)
- hdfs (2)
- python_socket (2)
- date (2)
- elasticsearch (1)
- jetty (1)
- 树 (1)
- 汽车 (1)
- mdrill (1)
- 车 (1)
- 日志 (1)
- web (1)
- 编译原理 (1)
- 信息检索 (1)
- 性能,linux (1)
- spam (1)
- 序列化 (1)
- fabric (2)
- guice (1)
- disruptor (1)
- executor (1)
- logback (2)
- 开源 (1)
- 设计 (1)
- 监控 (3)
- english (1)
- 问题记录 (1)
- Bitmap (1)
- 云计算 (1)
- 问题排查 (1)
- highchat (1)
- mac (3)
- docker (1)
- jdk (1)
- 表达式 (1)
- 网络 (1)
- 时间管理 (1)
- 时间序列 (1)
- OLAP (1)
- Big Table (0)
- sql (1)
- kafka (1)
- md5 (1)
- springboot (1)
- spring security (1)
- Spring Boot (3)
- mybatis (1)
- java8 (1)
- 分布式事务 (1)
- 限流 (1)
- Shadowsocks (0)
- 2018 (1)
- 服务治理 (1)
- 设计原则 (1)
- log (0)
- perftools (1)
最新评论
-
siphlina:
课程——基于Python数据分析与机器学习案例实战教程分享网盘 ...
Python机器学习库 -
san_yun:
leibnitz 写道hi,我想知道,无论在92还是94版本, ...
hbase的行锁与多版本并发控制(MVCC) -
leibnitz:
hi,我想知道,无论在92还是94版本,更新时(如Puts)都 ...
hbase的行锁与多版本并发控制(MVCC) -
107x:
不错,谢谢!
Latent Semantic Analysis(LSA/ LSI)算法简介 -
107x:
不错,谢谢!
Python机器学习库
ServerBootstrap
启动netty只需要三行代码:
package com.duitang.test; import java.net.InetSocketAddress; import java.util.concurrent.Executors; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.ChannelFactory; import org.jboss.netty.channel.socket.oio.OioServerSocketChannelFactory; /** * StringDecoder tester * @author yunpeng * */ public class StringDecoderTester { public static void main(String[] args) { ChannelFactory channelFactory = new OioServerSocketChannelFactory(Executors.newCachedThreadPool(),Executors.newCachedThreadPool()); ServerBootstrap bootStrap = new ServerBootstrap(channelFactory); bootStrap.bind(new InetSocketAddress(8888)); } }
ServerBootstrap是入口,复制启动netty。具体实现是委托给了ChannelFactory。这里是使用的OioServerSocketChannelFactory,OioServerSocketChannelFactory需要两个参数,一个是BossExcutor,一个WorkExcutor。BossExcutor负责不停的accept()到新的socket,然后提交给workExcutor,workExcutor负责监听socket的InputStream,当发现socket的InputStrea中有新的数据写入时,读取数据,然后通知给netty的消息框架进行处理。流程如下:
1. OioWorker.run() 负责监听一个socket的InputStream
2. Channels.fireMessageReceived() 发送消息
3. channel.getPipeline().sendUpstream(); 通知给pipline
自定义Hander
因为没有hander,所以日志里面会有警告:
警告: The pipeline contains no upstream handlers;
所以我们增加一个Hander:
static class StringTesterServerHandler extends SimpleChannelHandler { public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { ChannelBuffer buffer = (ChannelBuffer) e.getMessage(); String msg = buffer.toString("utf-8"); System.out.println(msg); buffer = ChannelBuffers.copiedBuffer("bye! \r\n", "utf-8"); ctx.getChannel().write(buffer); super.messageReceived(ctx, e); } }
public static void main(String[] args) { ChannelFactory channelFactory = new OioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()); ServerBootstrap bootStrap = new ServerBootstrap(channelFactory); ChannelPipeline pipeline = bootStrap.getPipeline(); pipeline.addLast("handler", new StringTesterServerHandler()); bootStrap.bind(new InetSocketAddress(8888)); }
echo 'fcuk' | nc localhost 8888
理解UpStream和DownStream
UpStream = InpuStream
DownStream = OutStream
SimpleChannelHandler
如果直接implements ChannelUpstreamHandler接口,实现其handleUpstream方法是不可行的,因为handleUpstream会被各种情况调用,需要判断各种Channel事件,SimpleChannelHandler提供了完整的实现,包括异常处理,关闭网络连接等:
public void handleUpstream( ChannelHandlerContext ctx, ChannelEvent e) throws Exception { if (e instanceof MessageEvent) { messageReceived(ctx, (MessageEvent) e); } else if (e instanceof WriteCompletionEvent) { WriteCompletionEvent evt = (WriteCompletionEvent) e; writeComplete(ctx, evt); } else if (e instanceof ChildChannelStateEvent) { ChildChannelStateEvent evt = (ChildChannelStateEvent) e; if (evt.getChildChannel().isOpen()) { childChannelOpen(ctx, evt); } else { childChannelClosed(ctx, evt); } } else if (e instanceof ChannelStateEvent) { ChannelStateEvent evt = (ChannelStateEvent) e; switch (evt.getState()) { case OPEN: if (Boolean.TRUE.equals(evt.getValue())) { channelOpen(ctx, evt); } else { channelClosed(ctx, evt); } break; case BOUND: if (evt.getValue() != null) { channelBound(ctx, evt); } else { channelUnbound(ctx, evt); } break; case CONNECTED: if (evt.getValue() != null) { channelConnected(ctx, evt); } else { channelDisconnected(ctx, evt); } break; case INTEREST_OPS: channelInterestChanged(ctx, evt); break; default: ctx.sendUpstream(e); } } else if (e instanceof ExceptionEvent) { exceptionCaught(ctx, (ExceptionEvent) e); } else { ctx.sendUpstream(e); } }
查看上面代码发现,只有ChannelEvent属于MessageEvent时才是我们真正需要关心的,所以只要重写messageReceived方法既可。
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception { ChannelBuffer buffer = ChannelBuffers.copiedBuffer("hello", "utf-8"); ctx.getChannel().write(buffer); super.messageReceived(ctx, e); }
注意,这里需要super.messageReceived(), 因为上层调用了 ctx.sendUpstream(e);查看DefaultChannelHandlerContext.sendUpstream()发现会通知下一个的hander:
public void sendUpstream(ChannelEvent e) { DefaultChannelHandlerContext next = getActualUpstreamContext(this.next); if (next != null) { DefaultChannelPipeline.this.sendUpstream(next, e); } }
报文frame
报文frame的问题,即由于这种状态机模型,你的某个channel每收到一段buffer,虽然顺序是保证的,但是完整性就不一定了。就好像我 们自己写传统socket要循环读一样,你这里同样要循环读,读到完整可解析的一整个frame方能解析,这个问题应该也不是netty独有的,除非你以 前写socket应用都是侥幸没有被网卡被操作系统被网关路由器之类的切过包。。。
netty有dynamicBuffer,就是用来聚集frame的,当然你也可以通过它提供的decoder来保证frame。
发表评论
-
Netty笔记ReplayingDecoder
2013-03-15 11:39 1313为什么需要ReplayingDecoder,它和FrameD ... -
netty StringDecoderTester
2013-02-21 16:55 1030netty package com.duita ... -
netty文档集合
2013-02-10 13:17 1112Netty 3.1 中文用户手册(一)-序言 Netty ... -
TransferQueue
2013-02-08 14:55 1593在看netty的代码实现发 ... -
ChannelBuffer介绍介绍
2012-11-07 11:28 837A random and sequential ... -
FrameDecoder介绍
2012-11-05 18:26 1206FrameDecoder 负责 decodes ... -
Netty服务器线程模型概览
2012-10-08 16:57 10876一切从ServerBootstrap开始 ServerB ... -
netty源代码分析
2012-10-08 16:35 963这篇文章(http://san-yun.iteye.com/b ... -
netty ExecutionHandler
2012-10-08 16:34 1524前面(http://san-yun.iteye.com/blo ... -
netty ChannelFuture
2012-10-08 14:12 1336在Netty中所有的io操作都是异步的,这也就是意味任何io访 ... -
netty的一点学习笔记
2012-10-02 22:57 1068原文:http://macrochen.iteye.com/b ... -
Netty实现原理浅析
2012-09-29 15:47 1352Netty是JBoss出品的高效的Java NIO开发框架, ... -
Netty代码分析
2012-09-29 13:22 771参考:http://rdc.taobao.co ... -
netty初探
2011-05-24 15:56 1615netty API //启动类 Server ...
相关推荐
接着,通过一系列逐步进阶的案例,如构建简单的Echo服务器、处理HTTP请求、实现WebSocket通信,读者将深入理解如何使用Netty进行网络编程。 在处理TCP连接方面,书中会详细讲解如何建立、管理和关闭连接,以及如何...
5. **即时聊天实战**:书中会介绍如何使用Netty构建一个简单的即时聊天应用,涉及用户注册、登录、消息发送、接收等核心功能的实现。 6. **性能优化**:Netty的性能优化策略,如内存管理、线程模型调整、缓冲区复用...
以下是对 Netty 的详细介绍以及如何通过代码示例进行学习。 一、Netty 框架基础 Netty 是由 JBoss 组织开源的一个网络通信框架,基于 Java NIO(非阻塞I/O)构建,提供了一套高度抽象和优化的 API,使得开发者可以...
文档还会介绍如何进行连接管理、读写操作、心跳检测、流量控制等网络编程的关键技术。 在实际开发中,了解并掌握Netty的API和设计理念,不仅可以提高网络应用的性能,还能极大地提升开发效率,降低维护成本。因此,...
本文将介绍 Java NIO 框架 Netty 的简单使用示例,通过示例代码,展示如何使用 Netty 实现一个服务器和客户端的网络通信。 Netty 的优点 1. 高性能:Netty 通过使用 NIO 模式,实现了高性能的网络编程。 2. 简单...
用户手册首先介绍了 Netty 的架构总览,强调了 Netty 在解决网络编程中通用问题时的高效性。Netty 采用了拦截链模式的事件模型和基于POJO的编程模型,使得开发者可以更加关注业务逻辑,而不用关心底层的通信细节。...
对于HTTP,Netty提供了对HTTP/1.x和HTTP/2的支持,包括WebSocket协议,使得开发Web服务和实时通信应用变得简单。 在性能优化方面,Netty提供了零拷贝(Zero-Copy)技术,通过减少数据在内存中的复制,提升了网络...
该章节详细介绍了Netty的基本概念和技术栈,并通过简单的示例程序引导读者入门。 - **架构总览**:对于希望深入了解Netty内部工作原理的读者,建议先阅读“架构总览”章节。这部分内容将帮助理解Netty是如何组织...
在Netty讲解-基础的压缩包中,可能包含了关于Netty基本概念、Channel、EventLoop、ByteBuf、Handler、Pipeline等组件的介绍,以及如何创建简单的Netty服务器和客户端的示例代码。这些内容将帮助初学者快速理解和上手...
Netty是一个异步事件驱动的网络应用程序框架,它为高性能、高可用性的网络服务器和客户端提供了一种简单易用的方式。本实践将详细介绍如何在Android环境中使用Netty进行客户端和服务端的通信。 首先,我们需要理解...
Netty用户指南还会介绍“编写一个应答服务器”,这是一个能够接收消息并回复相同消息的简单示例,用于展示如何在Netty中实现基本的请求响应模式。 时间服务器和时间客户端的示例会讲解如何使用Netty进行远程过程...
通过对Netty的总体结构、网络模型以及缓冲机制的介绍,我们可以看出Netty在设计上充分考虑了高性能和灵活性的需求。它不仅提供了简洁易用的API,还通过灵活的配置选项让开发者可以根据具体的业务场景进行定制化调整...
Netty 案例集锦系列文章介绍 Netty 入门比较简单,主要原因有如下几点: 1. Netty 的 API 封装比较简单,将复杂的网络通信通过 BootStrap 等工具类做 了二次封装,用户使用起来比较简单;
本手册主要介绍如何使用Netty来解决在网络应用开发过程中遇到的问题,并提供了一系列实践案例。 #### 二、Netty解决的实际问题 - **标题**:问题篇 - **描述**:现代网络应用经常使用通用的目的应用程序或库进行...
12. **WebSocket支持**:Netty提供了WebSocket协议的完整实现,包括握手和消息编码解码,使开发WebSocket应用变得简单。 《Netty权威指南(第二版)》这本书将详细介绍这些知识点,并通过实例讲解如何在实践中应用...
首先,会介绍Bootstrap类,它是Netty服务端的启动器,通过它可以配置服务器的参数,如绑定的端口、事件循环组等。接着,讲解ChannelHandler,它是处理网络事件的主要组件,可以实现自定义的业务逻辑。ChannelFuture...
本书是为想要或者正在使用Java从事高性能网络编程的人而写的,循序渐进地介绍了Netty各个方面的内容。 本书共分为4个部分:第一...此外,附录部分还会简单地介绍Maven,以及如何通过使用Maven编译和运行本书中的示例。