零、socket:

http://haohaoxuexi.iteye.com/blog/1979837

一、NIO(1.0)非阻塞

  • NIO的特点:
    1. Buffer,缓冲区
    2. Channel,管道
    3. 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的特点:
  1. 责任链,和tomcat中的fitter类似(最后结果交给servlet)避免请求的发送者和接受者直接的耦合关系。
  2. 异步

Netty的异步事件驱动模型主要涉及到下面几个核心的概念:

  1. Channel:表示一个与socket关联的通道
  2. ChannelPipeline: 管道,一个Channel拥有一个ChannelPipeline,ChannelPipeline维护着一个处理链(严格的说是两 个:upstream、downstream),处理链是由很多处理句柄ChannelHandler所构成,每个ChannelHandler处理完以 后会传递给链中的下一个处理句柄继续处理。
  3. ChannelHandler:处理句柄,用户可以定义自己的处理句柄来处理每个请求,或发出请求前进行预处理,典型的有编码/解码器:decoder、encoder。
  4. ChannelEvent:事件,是整个模型的处理对象,当产生或触发(fire)一个事件时,该事件会沿着ChannelPipeline处理链依次被处理。
  5. ChannelFuture: 异步结果,这个是异步事件处理的关键,当一个事件被处理时,可以直接以ChannelFuture的形式直接返回,不用在当前操作中被阻塞。可以通过 ChannelFuture得到最终的执行结果,具体的做法是在ChannelFuture添加监听器listener,当操作最终被执行完 后,listener会被触发,我们可以在listener的回调函数中预定义我们的业务代码。

五、如何使用netty,netty的demo

  1. 建立连接池
  2. 继承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的资料

  1. 《netty权威指南》
  2. http://www.cnblogs.com/java-my-life/archive/2012/05/28/2516865.html
  3. http://www.cnblogs.com/NanguoCoffee/archive/2010/12/10/1902491.html

八、netty的相关讨论

  1. 为什么说netty是异步的?允许客户端最大的同时连接数:服务器有开放那么多文件句柄数 支持那么多长连接 只要服务器资源够就行,另外tomcat自己也会限制连接数。netty的异步体现在:1、服务端不持有连接,使用的是轮询的方法2、channel通道是异步的3、使用了channel future回调
  2. netty如何编码解码,TCP自带了拆包粘包的功能,netty把他们封装好了,然后处理内容我们需要自己实现

netty-学习笔记的更多相关文章

  1. Netty学习笔记(二) 实现服务端和客户端

    在Netty学习笔记(一) 实现DISCARD服务中,我们使用Netty和Python实现了简单的丢弃DISCARD服务,这篇,我们使用Netty实现服务端和客户端交互的需求. 前置工作 开发环境 J ...

  2. Netty 学习笔记(1)通信原理

    前言 本文主要从 select 和 epoll 系统调用入手,来打开 Netty 的大门,从认识 Netty 的基础原理 —— I/O 多路复用模型开始.   Netty 的通信原理 Netty 底层 ...

  3. Netty学习笔记-入门版

    目录 Netty学习笔记 前言 什么是Netty IO基础 概念说明 IO简单介绍 用户空间与内核空间 进程(Process) 线程(thread) 程序和进程 进程切换 进程阻塞 文件描述符 文件句 ...

  4. Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例

    在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...

  5. Netty学习笔记(二)——netty组件及其用法

    1.Netty是 一个异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 原生NIO存在的问题 1) NIO的类库和API繁杂,使用麻烦:需要熟练掌握Selector.Se ...

  6. Netty学习笔记(一)

    学习圣思园Netty笔记,个人理解 2.netty宏观理解-本节内容: 1.阶段性事件驱动,一个请求分为若干阶段处理,每个阶段根据情况合理分配线程去处理,各阶段间通信采用异步事件驱动方式. 2.net ...

  7. Netty学习笔记(一):接收nodejs模拟表单上传的文件

    好久不写博客了,也好久不写代码了,这两天临时遇上一个事情,觉得不难,加上觉得手有些生,就动手做了一下,结果遇上了不少坑,有新坑,有老坑,痛苦无比,现在总算差不多了,赶紧记录下来,希望以后不再重复这种痛 ...

  8. 2018/1/19 Netty学习笔记(一)

    这段时间学了好多好多东西,不过更多是细节和思想上的,比如分布式事物,二次提交,改善代码质量,还有一些看了一些源码什么的; 记录一下真正的技术学习,关于Netty的学习过程; 首先说Netty之前先说一 ...

  9. Netty学习笔记(三) 自定义编码器

    编写一个网络应用程序需要实现某种编解码器,编解码器的作用就是讲原始字节数据与自定义的消息对象进行互转.网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码, ...

  10. Netty学习笔记(番外篇) - ChannelHandler、ChannelPipeline和ChannelHandlerContext的联系

    这一篇是 ChannelHandler 和 ChannelPipeline 的番外篇,主要从源码的角度来学习 ChannelHandler.ChannelHandler 和 ChannelPipeli ...

随机推荐

  1. google关于ssh key的解释(转)转的google的wiki的

    SSH keys (简体中文)     SSH 密钥对可以让您方便的登录到 SSH 服务器,而无需输入密码.由于您无需发送您的密码到网络中,SSH 密钥对被认为是更加安全的方式.再加上使用密码短语 ( ...

  2. Python下安装MySQLdb

    前提是你已经安装过mysql 1.从https://pypi.python.org/pypi/MySQL-python/下载MySQL-python,然后用rz命令上传到相关目录 2.用tar -zx ...

  3. SQL Server占用内存的认识

    SQL Server占用的内存主要由三部分组成:数据缓存(Data Buffer).执行缓存(Procedure Cache).以及SQL Server引擎程序.SQL Server引擎程序所占用缓存 ...

  4. JavaWeb学习之Path总结、ServletContext、ServletResponse、ServletRequest(3)

    1.Path总结 1.java项目 1 File file = new File(""); file.getAbsolutePath(); * 使用java命令,输出路径是,当前j ...

  5. iscroll 4.0 滚动(水平和垂直)

    1.概述 iscroll 专注于页面滚动js.Iscroll滚动做的挺好,特别是针对手机网页(android.iphone)正好弥补手动滑屏的遗缺,而今研究一番,把代码贴出来,供大家参考. 2.isc ...

  6. siblings 使用

    //$(object).siblings().each(function () { // $(this).find("img").attr("class", & ...

  7. MyEclipse 关闭鼠标悬停提示

    preference --> MyEclipse -->Files and Editors--> Common Editor Preference --> Hovers 把里面 ...

  8. Linux环境下stl库使用(vector)

    step1: #include <iostream> #include <vector> #include <string> using namespace std ...

  9. wp8 入门到精通 Gallery

    <Grid x:Name="LayoutRoot" Background="Transparent"> <Grid.Resources> ...

  10. PHP利用jquery生成各种验证码和Ajax验证

    PHP生成验证码图片 PHP生成验证码的原理:使用PHP的GD库,生成一张带验证码的图片,并将验证码保存在Session中.PHP 生成验证码的大致流程有: .产生一张png的图片: .为图片设置背景 ...