NIO 之 Channel实现原理
来源:互联网 发布:java nanotime 唯一 编辑:程序博客网 时间:2024/06/05 20:21
相关文章
IO、NIO、AIO 内部原理分析
NIO 之 Selector实现原理
NIO 之 ByteBuffer实现原理
NIO概述
Java NIO 由以下几个核心部分组成:
- Channels
- Buffers
- Selectors
在传统IO中,流是基于字节的方式进行读写的。
在NIO中,使用通道(Channel)基于缓冲区数据块的读写。
Channel 和 IO 流的区别
Java NIO的通道类似IO中的流,但又有些不同:
- 既可以从通道中读取数据,又可以写数据到通道。但流的读写通常是单向的。
- 通道可以异步地读写。
- 通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。
Channel 实现类
下面是JAVA NIO中的一些主要Channel的实现:
- FileChannel
FileChannel 从文件中读写数据。 - DatagramChannel
DatagramChannel 能通过UDP读写网络中的数据。 - SocketChannel
SocketChannel 能通过TCP读写网络中的数据。 - ServerSocketChannel
ServerSocketChannel可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。
FileChannel 是基于文件的Channel。
DatagramChannel、SocketChannel、ServerSocketChannel 都是基于网络流的Channel。
下面我们主要介绍关于基于网络流的SocketChannel 和 ServerSocketChannel 。
register 方法
基于网络流的Channel中提供了register方法。
使用示例:
channel.register(selector, Selectionkey.OP_READ, ByteBuffer.allocate(64));
代码的写法感觉是要将selector对象注册到channel中。其实正好相反,应该是将channel注册到selector中。
下面通过代码分析:
![将channel 注册到 selector 中]
1.首先判断 selector 中是否已经注册此 channel ,如果注册过就更新注册的事件和attach附件信息。
2. 如果 selector 没有注册过 channel ,则将 channel 注册到 selector 中。
configureBlocking 方法
public final SelectableChannel configureBlocking(boolean block)
Channel 默认使用阻塞模式,通过 configureBlocking 方法可以将该 Channel 设置成非阻塞模式。
//设置成非阻塞模式channel.configureBlocking(false);
ServerSocketChannel
ServerSocketChannel只支持入站连接请求。不提供读取、写入数据功能。
accept 方法
public abstract SocketChannel accept()
accept()可以在阻塞或非阻塞模式下操作。
- 阻塞模式
accept()方法等待入站连接。然后它接受一个连接,并返回到远程客户端的一个SocketChannel。在建立连接前你无法做任何操作。
示例:
public static void blockMode(){ try { ServerSocketChannel serverChannel = ServerSocketChannel.open(); //绑定要监控的端口 serverChannel.bind(new InetSocketAddress(9000)); //获取入站请求socketChannel SocketChannel clientChannel = serverChannel.accept(); ... } catch (Exception e) { }}
- 非阻塞模式
如果没有入站连接,accept()返回null。非阻塞模式一般和Selector结合使用。
示例:
public static void nonBlockMode(){ try { //创建一个selector Selector selector = Selector.open(); //创建一个ServerSocketChannel ServerSocketChannel serverChannel = ServerSocketChannel.open(); //设置成非阻塞模式 serverChannel.configureBlocking(false); //绑定要监控的端口 serverChannel.bind(new InetSocketAddress(9000)); //接受入站请求 serverChannel.accept(); //将 serverChannel 注册到 selector 上 serverChannel.register(selector, SelectionKey.OP_READ); } catch (Exception e) { }}
SocketChannel
SocketChannel 类可以读写TCP Socket。数据必须编码到ByteBuffer对象中来完成读写。
open 方法
- public static SocketChannel open()
创建一个SocketChannel,但不连接(没有指定目标ip和port),如果想使用非阻塞模式则使用该方法创建SocketChannel对象。
示例:
public static void nonSocketChannel() throws Exception { SocketChannel client = SocketChannel.open(); client.configureBlocking(false); client.connet(new InetSocketAddress("192.168.1.10", 9000));}
- public static SocketChannel open(SocketAddress remote)
构造SocketChannel 对象,并使用阻塞模式连接目标地址。
connect 方法
public abstract boolean connect(SocketAddress remote)
非阻塞模式下,如果要连接远程服务器必须使用 connect 方法进行连接。
finishConnect 方法
public abstract boolean finishConnect()
阻塞模式:直接返回true,因为在构造SocketChannel的时候已经建立连接了。
非阻塞模式下:必须调用此方法来判断该方法是否已经建立网络连接,只有建立网络连接后才能进行读写操作。
判断网络连接状态
public abstract boolean isConnected()
判断是否已经连接。
public abstract boolean isConnectionPending()
判断连接是否正在连接状态
read 方法
- public int read(ByteBuffer buf)
将 SocketChannel 中的数据读入填充到 buf 中 - public final long read(ByteBuffer[] dsts)
将 SocketChannel 中的数据读入填充到 dsts[] 数组。按照数组顺序进行填充。 - public long read(ByteBuffer[] dsts, int offset, int length)
将 SocketChannel 中的数据填充到 dsts[] 数组中,从第数组中的offset坐标开始填充,填充 length 个Bytebuffer。
write 方法
- public int write(ByteBuffer src)
将 buf 中的数据写入到 SocketChannel 中 - public final long write(ByteBuffer[] srcs)
将 srcs[] 数组中的数据写入到 SocketChannel 中,按照数组顺序一个一个写入。 - public long write(ByteBuffer[] srcs, int offset, int length)
将 srcs[] 数组中的数据写入到 SocketChannel 中,从数组中 offset 坐标开始,写入length个ByteBuffer对象。
本人简书blog地址:http://www.jianshu.com/u/1f0067e24ff8
点击这里快速进入简书
GIT地址:http://git.oschina.net/brucekankan/
点击这里快速进入GIT
- NIO 之 Channel实现原理
- NIO之Buffer channel
- Java NIO之Channel
- 二、Nio之Channel
- NIO之Buffer、Channel
- NIO 之 ByteBuffer实现原理
- NIO 之 Selector实现原理
- 解读java nio之channel
- 《JAVA NIO》之Channel类图
- java nio 之 初识 channel
- Java 之NIO(二) - Channel
- java NIO之socket channel
- Java NIO之Channel学习
- NIO之channel与selector
- NIO通道(channel)原理与获取
- NIO channel
- NIO Channel
- java NIO 之 buffer and channel
- 网易2017春招笔试编程题 分饼干
- 使用统计学习计算选出所有牌有效且没有无效牌的概率
- 洛谷 P2668 斗地主
- 按量付费实例批量更改实例带宽
- 什么是二维数组
- NIO 之 Channel实现原理
- C# WinForm中的提示
- 设计模式学习—中介者模式(Mediator Design Pattern)
- Profinet从站开发(4)- EB200P step by step (编译PN协议栈)
- C语言实现冒泡排序和简单选择排序
- 在类的const成员函数中使用map的iterator
- 并发Concurrent
- springMVC入门程序
- NIO 之 Selector实现原理