零、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. JAVA addShutdownHook测试

    public static void main(String[] args) { System.out.println("1111111111"); try { Thread.sl ...

  2. JS打造的跟随鼠标移动的酷炫拓扑图案

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. 384. Shuffle an Array

    Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] n ...

  4. Rotate partitions in DB2 on z

    Rotating partitions   You can use the ALTER TABLE statement to rotate any logical partition to becom ...

  5. NYOJ题目97兄弟郊游问题

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAr8AAAHxCAIAAADrwUM4AAAgAElEQVR4nO3dLXLjytfH8f8mzLOQYC

  6. 《CLR via C#》读书笔记(5)基元类型、引用类型和值类型

    5.1 基元类型 编译器直接支持的数据类型称为基元类型(primitive type). 以下4行到吗生成完全相同的IL int a = 0; //最方便的语法 System.Int32 b = 0; ...

  7. Linux安装mysql最新版本纪要

    http://blog.csdn.net/frt007/article/details/50184143 http://blog.csdn.net/wb96a1007/article/details/ ...

  8. Delphi开发中各种文件扩展名代表什么文件

    暂时就遇到了以下这几种,以后遇到再进行补充 .DPR Delphi Project文件,打开这个文件,就会打开所有的编程的代码文件.包含了Pascal代码 .PAS Pascal文件,Pascal单元 ...

  9. 无废话ExtJs 入门教程十四[文本编辑器:Editor]

    无废话ExtJs 入门教程十四[文本编辑器:Editor] extjs技术交流,欢迎加群(201926085) ExtJs自带的编辑器没有图片上传的功能,大部分时候能够满足我们的需要. 但有时候这个功 ...

  10. linux中socket的理解

    对linux中socket的理解 一.socket 一般来说socket有一个别名也叫做套接字. socket起源于Unix,都可以用“打开open –> 读写write/read –> ...