netty-学习笔记
零、socket:
http://haohaoxuexi.iteye.com/blog/1979837
一、NIO(1.0)非阻塞
- NIO的特点:
- Buffer,缓冲区
- Channel,管道
- Selector,多路复用选择器
- NIO的步骤:
二、AIO(NIO2.0)异步非阻塞
使用了异步的channel,调用jdk底层的回掉函数,异步处理。
三、什么是netty(基于NIO2.0)
Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming such as TCP and UDP socket server.
四、为什么使用netty
远古:使用的是io,近代是nio,现在是netty(已经封装好了的,相对与nio,API更加的简单)
- netty的特点:
- 责任链,和tomcat中的fitter类似(最后结果交给servlet)避免请求的发送者和接受者直接的耦合关系。
- 异步
Netty的异步事件驱动模型主要涉及到下面几个核心的概念:
- Channel:表示一个与socket关联的通道
- ChannelPipeline: 管道,一个Channel拥有一个ChannelPipeline,ChannelPipeline维护着一个处理链(严格的说是两 个:upstream、downstream),处理链是由很多处理句柄ChannelHandler所构成,每个ChannelHandler处理完以 后会传递给链中的下一个处理句柄继续处理。
- ChannelHandler:处理句柄,用户可以定义自己的处理句柄来处理每个请求,或发出请求前进行预处理,典型的有编码/解码器:decoder、encoder。
- ChannelEvent:事件,是整个模型的处理对象,当产生或触发(fire)一个事件时,该事件会沿着ChannelPipeline处理链依次被处理。
- ChannelFuture: 异步结果,这个是异步事件处理的关键,当一个事件被处理时,可以直接以ChannelFuture的形式直接返回,不用在当前操作中被阻塞。可以通过 ChannelFuture得到最终的执行结果,具体的做法是在ChannelFuture添加监听器listener,当操作最终被执行完 后,listener会被触发,我们可以在listener的回调函数中预定义我们的业务代码。
五、如何使用netty,netty的demo
- 建立连接池
- 继承netty父类实现方法
TimeServer
package com.wanghongye.Netty; 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; /**
* @Description :netty服务端
* @author :王红叶
* @date(创建日期):2015年9月22日 下午5:15:22
* @company(公司):深圳市彩讯科技有限公司
*
* @History(修改历史):
*/
public class TimeServer
{ public void bind(int port) throws Exception
{
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup(); try
{
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workGroup).channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChildChannelHandler()); ChannelFuture f = b.bind(port).sync(); f.channel().closeFuture().sync();
}
finally
{
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
} private class ChildChannelHandler extends ChannelInitializer<SocketChannel>{ @Override
protected void initChannel(SocketChannel arg0) throws Exception
{
arg0.pipeline().addLast(new TimeChannelHandler());
}
} public static void main(String[] args) throws Exception
{
int port = 8080;
if(args != null && args.length>0){
port = Integer.valueOf(args[0]);
}
new TimeServer().bind(port);
}
}
TimeChannelHandler
package com.wanghongye.Netty; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; /**
* Netty处理类
* @Description :
* @author :王红叶
* @date(创建日期):2015年9月22日 下午4:54:06
* @company(公司):深圳市彩讯科技有限公司
*
* @History(修改历史):
*/
public class TimeChannelHandler extends ChannelHandlerAdapter
{
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception
{
ByteBuf byteBuf = (ByteBuf) msg;
byte[] req = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(req); String body = new String(req, "UTF-8");
System.out.println("*********" + body);
String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(body) ? new java.util.Date(
System.currentTimeMillis()).toString() : "BAD ORDER";
ByteBuf byteBufReps = Unpooled.copiedBuffer(currentTime.getBytes());
ctx.write(byteBufReps); } public void channelReadComplete(ChannelHandlerContext ctx)
{
ctx.close();
} public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception
{
ctx.close();
} }
TimeClient
package com.wanghongye.Netty; import io.netty.bootstrap.Bootstrap;
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.NioSocketChannel; /**
* @Description :netty的客户端
* @author :王红叶
* @date(创建日期):2015年9月22日 下午5:09:54
* @company(公司):深圳市彩讯科技有限公司
*
* @History(修改历史):
*/
public class TimeClient
{
public void connet(int port, String host) throws Exception
{
EventLoopGroup group = new NioEventLoopGroup();
try
{
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group).channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChildChannelHandler()); ChannelFuture f = bootstrap.connect(host, port).sync();
f.channel().closeFuture().sync();
}
finally
{
group.shutdownGracefully();
}
} private class ChildChannelHandler extends ChannelInitializer<SocketChannel>
{ @Override
protected void initChannel(SocketChannel arg0) throws Exception
{
arg0.pipeline().addLast(new TimeChannelClientHandler());
}
} public static void main(String[] args) throws Exception
{
int port = 8080;
if (args != null && args.length > 0)
{
port = Integer.valueOf(args[0]);
}
new TimeClient().connet(port, "127.0.0.1");
}
}
TimeChannelClientHandler
package com.wanghongye.Netty; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; public class TimeChannelClientHandler extends ChannelHandlerAdapter
{
private final ByteBuf buf; public TimeChannelClientHandler()
{
byte[] req = "QUERY TIME ORDER".getBytes();
buf = Unpooled.buffer(req.length);
buf.writeBytes(req);
} public void channelActive(ChannelHandlerContext ctx)
{
ctx.writeAndFlush(buf);
} public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
{
ByteBuf byteBuf = (ByteBuf) msg;
byte[] req = new byte[byteBuf.readableBytes()];
byteBuf.readBytes(req); String body = new String(req, "UTF-8");
System.out.println("###########" + body);
} public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception
{
ctx.close();
}
}
(NO RUN SUCCESS)
六、项目中如何使用netty
在pns(TCP是同步的)和统一配置中使用netty,主要使用了netty的异步和socket。
七、关于netty的资料
- 《netty权威指南》
- http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
- http://www.cnblogs.com/NanguoCoffee/archive/2010/12/10/1902491.html
八、netty的相关讨论
- 为什么说netty是异步的?允许客户端最大的同时连接数:服务器有开放那么多文件句柄数 支持那么多长连接 只要服务器资源够就行,另外tomcat自己也会限制连接数。netty的异步体现在:1、服务端不持有连接,使用的是轮询的方法2、channel通道是异步的3、使用了channel future回调
- netty如何编码解码,TCP自带了拆包粘包的功能,netty把他们封装好了,然后处理内容我们需要自己实现
netty-学习笔记的更多相关文章
- Netty学习笔记(二) 实现服务端和客户端
在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...
- Netty 学习笔记(1)通信原理
前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始. Netty 的通信原理 Netty 底层 ...
- Netty学习笔记-入门版
目录 Netty学习笔记 前言 什么是Netty IO基础 概念说明 IO简单介绍 用户空间与内核空间 进程(Process) 线程(thread) 程序和进程 进程切换 进程阻塞 文件描述符 文件句 ...
- Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例
在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...
- Netty学习笔记(二)——netty组件及其用法
1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...
- Netty学习笔记(一)
学习圣思园Netty笔记,个人理解 2.netty宏观理解-本节内容: 1.阶段性事件驱动,一个请求分为若干阶段处理,每个阶段根据情况合理分配线程去处理,各阶段间通信采用异步事件驱动方式. 2.net ...
- Netty学习笔记(一):接收nodejs模拟表单上传的文件
好久不写博客了,也好久不写代码了,这两天临时遇上一个事情,觉得不难,加上觉得手有些生,就动手做了一下,结果遇上了不少坑,有新坑,有老坑,痛苦无比,现在总算差不多了,赶紧记录下来,希望以后不再重复这种痛 ...
- 2018/1/19 Netty学习笔记(一)
这段时间学了好多好多东西,不过更多是细节和思想上的,比如分布式事物,二次提交,改善代码质量,还有一些看了一些源码什么的; 记录一下真正的技术学习,关于Netty的学习过程; 首先说Netty之前先说一 ...
- Netty学习笔记(三) 自定义编码器
编写一个网络应用程序需要实现某种编解码器,编解码器的作用就是讲原始字节数据与自定义的消息对象进行互转.网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码, ...
- Netty学习笔记(番外篇) - ChannelHandler、ChannelPipeline和ChannelHandlerContext的联系
这一篇是 ChannelHandler 和 ChannelPipeline 的番外篇,主要从源码的角度来学习 ChannelHandler.ChannelHandler 和 ChannelPipeli ...
随机推荐
- MVC4方法行为过滤器例子(用户登录)
在Model文件夹下添加一个类MyActionFilterAttribute继承于ActionFilterAttribute: using System; using System.Collectio ...
- SQLServer自定义函数简单演示
CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ][ type_schema_name. ] par ...
- spring整合httpclient
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://w ...
- 瓦片地图与geoserver发布
本文主要包括以下内容 TileMill生成Tile影像金字塔(.mbtiles压缩文件) Mbutil(https://github.com/mapbox/mbutil)解压缩 Apache HTTP ...
- 20145206邹京儒《Java程序设计》课程总结
20145206邹京儒<Java程序设计>课程总结 (按顺序)每周读书笔记链接汇总 第一周:http://www.cnblogs.com/ZouJR/p/5213572.html http ...
- JavaScript基础——定义变量
在JavaScript中使用变量来临时存储和访问来自JavaScript文件的数据.变量既可以指向简单的数据类型,如数字或者字符串:也可以指向更复杂的数据类型,比如对象. 在JavaScript中定义 ...
- Android Tab -- 使用ViewPager、Fragment、FragmentPagerAdapter来实现
原文地址:http://blog.csdn.net/crazy1235/article/details/42678877 效果:滑动切换:点击标签切换. 代码:https://github.com/l ...
- zTree控件的使用
最常用的使用方式是json格式 .net递归实现对象生成json格式字符串 代码: using System; using System.Collections.Generic; using Syst ...
- 【mysql中myisam和innodb的区别】
单击进入源网页 要点摘要: 1.查看mysql存储引擎的状态mysql> show engines; 2.查看mysql默认的存储引擎mysql> show variables like ...
- 自制工具:迅速打开一个Node 环境的Playground
需求 经常有这种情况,写代码的时候需要实验种想法,亟需一种playground 环境来玩耍.如果是前端的话可以打开chrome 的控制台,但是如果是Node 的话就比较麻烦了.我要打开我的存放试验代码 ...