Netty实战读书笔记(第四章)
来源:互联网 发布:在淘宝上怎样发链接 编辑:程序博客网 时间:2024/05/21 12:41
Netty实战第四章:传输
比较java自带的OIO、NIO、Netty提供的OIO、Netty提供的NIO。
OIO:
import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class PlainOioServer {final int port = 8888;public void server() throws IOException{// 绑定端口final ServerSocket server = new ServerSocket(this.port);try {while(true){// 阻塞接受请求final Socket socket = server.accept();// 开启新线程处理请求。new Thread(new Runnable(){public void run(){try {InputStream input = socket.getInputStream();OutputStream output = socket.getOutputStream();output.write("ok".getBytes());output.flush();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally{server.close();}}}NIO
import java.io.IOException;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.util.Iterator;import java.util.Set;public class PlainNioServer {private int port = 8888;public void server() throws IOException{final ServerSocketChannel channel = ServerSocketChannel.open();// 开启channelServerSocket serverSocket = channel.socket();serverSocket.bind(new InetSocketAddress(this.port));// 将serverSocket绑定到指定端口。Selector select = Selector.open();// 打开selector,将channel注册到selector中。channel.register(select, SelectionKey.OP_ACCEPT); // selector注册为可接收请求。final ByteBuffer msg = ByteBuffer.wrap("ok".getBytes());while(true){select.select();// 阻塞直到新的事件到达。Set<SelectionKey> keys = select.selectedKeys();// 获取所有事件的keys。Iterator<SelectionKey> it = keys.iterator();while(it.hasNext()){SelectionKey key = it.next();if (key.isAcceptable()){} if (key.isWritable()){}}}}}
Netty自带的OIO:
import java.net.InetSocketAddress;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.oio.OioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.oio.OioServerSocketChannel;public class NettyOioServer {private int port ;public NettyOioServer(int port ){this.port = port;}public void server(){EventLoopGroup group = new OioEventLoopGroup();// 创建阻塞型io。try {ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(group).channel(OioServerSocketChannel.class)// IO类型不同,指定socketchannel为阻塞类型。.localAddress(new InetSocketAddress(this.port))// 将server绑定到指定端口上.childHandler(new ChannelInitializer<SocketChannel>(){@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// TODO Auto-generated method stubch.pipeline().addLast(new ChannelInboundHandlerAdapter(){@Overridepublic void channelRead(ChannelHandlerContext ct , Object msg){}@Override public void channelReadComplete(ChannelHandlerContext ct ){}});}});ChannelFuture future = bootstrap.bind().sync();// 应该是现有bootstrap执行bind到channelFuture上future.channel().closeFuture().sync();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {try {group.shutdownGracefully().sync();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
Netty自带的NIO:
import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.ChannelInboundHandlerAdapter;import io.netty.channel.ChannelInitializer;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;public class NettyNioServer {private int port ;public NettyNioServer(int port ){this.port = port;}public void server() throws InterruptedException{EventLoopGroup group = new NioEventLoopGroup();try{ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(group).channel(NioServerSocketChannel.class)// 申明了IO类型.localAddress(new InetSocketAddress(this.port))//绑定了端口号.childHandler(new ChannelInitializer<SocketChannel>(){@Overrideprotected void initChannel(SocketChannel ch) throws Exception {// TODO Auto-generated method stubch.pipeline().addLast(new ChannelInboundHandlerAdapter(){// 处理客户端发来的信息@Overridepublic void channelRead(ChannelHandlerContext ctx , Object msg){}@Overridepublic void channelReadComplete(ChannelHandlerContext ctx){}});}});// 将启动器绑定到channelFuture 上,同步阻塞绑定。ChannelFuture future = bootstrap.bind().sync();// 获取channel,在执行完毕后关闭,同步阻塞关闭。future.channel().closeFuture().sync();} finally{group.shutdownGracefully().sync();}}}
java JDK自带的OIO和NIO属于不同的编程模式,Netty通过统一的编程规范,把NIO和OIO统一为相识的编程模式。
传输API:
每个channel都会被分配一个channelPipeLine和channelConfig,channelPipeline相当于channelHandler容器,通过将channelHandler add到pipeline中,管理channelHandler,形成适配器方式的管理, channelPipeline不仅包含处理事件,还包含需要处理的入站和出站的数据。
ChannelHandler处理的常规事件:
1 , 将数据从一种格式转换为另一种格式。比如decode、encode。
2 , 提供异常的通知。比如exceptionCaught。
3 , 提供给用户事件通知消息。
4 , 当channel注册到EventLoop或者从EventLoop注销时的通知。
channelPipeLine可以动态的向Pipeline中添加channelHandler,例如当需要支持STRATTLS协议时,可以向PIpeline中添加对应的handler,也实现了拦截器模式。
channel支持多线程操作,在多线程下也是安全的。
Netty数据传输:
Netty提供几种数据传输方法,不同的数据传输方式支持的协议不同,主要的数据传输方式:
1 , NIO,基于java NIO的数据传输方式,使用selector注册的方式。
2 , epoll,由JNI提供的epoll()支持。
Netty为linux提供的一组基于JNI的epoll()方法的NIO,如果应用程序在linux中运行,性能好于java自带的NIO。
3 , local,在VM内部传输数据。
提供了在同一个JVM中运行的客户端和服务器异步通信的API,在channel启动的时候就注册了,没有网络流量的交互,不能与其他方式交换数据。
4, OIO的方式。
阻塞的方式。
5 , embedding的方式。
- Netty实战读书笔记(第四章)
- Netty实战读书笔记(第二章)
- Netty实战读书笔记(第三章)
- Netty实战读书笔记(第六章)
- Netty实战读书笔记(第七章)
- Netty实战读书笔记(第七章)
- Netty实战读书笔记(第八章)
- Netty实战读书笔记(第十章)
- Netty In Action 读书笔记 - 第四章 传输
- Netty实战读书笔记(第五章(一))
- Netty实战读书笔记(第五章(二))
- Netty实战读书笔记(第十一章(上))
- Netty实战读书笔记(第十一章(下))
- Netty实战读书笔记(第一章概念梳理)
- Netty实战读书笔记四:Bootstrapping
- Netty实战读书笔记二:ChannelHandler和ChannelPipeline
- 《机器学习实战》读书笔记 第四章 朴素贝叶斯(part 1)
- 《机器学习实战》读书笔记 第四章 朴素贝叶斯(part 2)
- 第 3 次送书中奖名单(另附一个彩蛋)
- Android 彻底组件化番外篇-gradle3.0.0
- Ztree利用getNodesByFilter进行js搜索
- matlab保存变量(syms)到.txt文件中
- osgEarth js脚本绘制柱状图 10.feature_population_cylinders.earth
- Netty实战读书笔记(第四章)
- PCA数学原理
- vetur插件提示 [vue-language-server] Elements in iteration expect to have 'v-bind:key' directives错误的解决办法
- PostgreSQL pg_current_xlog_insert_location()与pg_current_xlog_location()
- 牛牛学堂:近期对玉米市场持观望态度
- 基础概念扫盲篇【记录】(持续更新)
- 上传文件限制导致413-Request Entity Too Large
- 成员变量和属性的区别
- 冒泡排序