NIO-Channel
NIO-Channel
目录
NIO-概览
NIO-Buffer
NIO-Channel
NIO-Channel接口分析
NIO-SocketChannel源码分析
NIO-FileChannel源码分析
NIO-Selector源码分析
NIO-WindowsSelectorImpl源码分析
NIO-EPollSelectorIpml源码分析
前言
本来是想学习Netty的,但是Netty是一个NIO框架,因此在学习netty之前,还是先梳理一下NIO的知识。通过剖析源码理解NIO的设计原理。
本系列文章针对的是JDK1.8.0.161的源码。
什么是Channel
通道(Channel)是对原I/O包中的流的模拟。与文件设备I/O交互的所有数据都必须通过一个Channel对象。
上一节我们提到在NIO中使用缓冲区来存放指定基元的数据,我们可以通过Buffer来读写数据。
将数据写入到硬盘时,我们可以将字节数据写入到缓冲区中;若我们要从硬盘读取数据,则需要通过通道将数据写入到缓冲区,然后再从缓冲区读取数据。
通道类型
根据不同的使用方式,分为不同的通道。比如我们需要网络读写,就需要网络交互的通道。需要文件读写就需要文件交互的通道。
NIO实现了Sctp协议、TCP协议、UDP协议以及文件传输四种通道,同时还实现了Windows平台的异步Socket通道以及异步文件通道。
windows平台的异步I/O是通过重叠I/O和IOCP(I/O完成端口)实现的,想要了解windows异步I/O的知识可以看一下我另一篇文章《Windows内核原理-同步IO与异步IO》
类型 | 通道 |
---|---|
Sctp协议客户端 | SctpChannel |
Sctp协议多播客户端 | SctpMultiChannel |
Sctp协议服务端 | SctpServerChannel |
UDP协议 | DatagramChannel |
TCP协议同步I/O服务端 | ServerSocketChannel |
TCP协议同步I/O客户端 | ServerChannel |
文件读写 | FileChannel |
对于Windows平台的异步通道
类型 | 通道 |
---|---|
TCP协议异步I/O服务端 | WindowsAsynchronousServerSocketChannel |
TCP协议异步I/O客户端 | WindowsAsynchronousSocketChannel |
异步文件读写 | WindowsAsynchronousFileChannel |
另外NIO还实现了一个单向通讯管道(Pipe)的功能,通过引入
SourceChannel
和SinkChannel
实现,底层实际还是Socket通讯。
如何使用
在介绍不同的Channel的实现之前我们先介绍下Channel如何使用。
ServerSocketChannel
以TCP协议为例,我们进行网络收发的时候,首先需要创建一个ServerSocketChannel用于监听端口。
//创建一个服务端socket通道用于接收连接
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
//绑定监听地址
serverSocketChannel.socket().bind(new InetSocketAddress(8080));
//等待连接
SocketChannel socketChannel = serverSocketChannel.accept();
我们监听了8080端口。若没有连接时,线程会阻塞在
accept
。
当有收到新的连接创建时,会获取到SocketChannel,此时我们需要创建一个Buffer用来从Channel中读取数据。
ByteBuffer buf = ByteBuffer.allocate(1024);
//数据将写入到buffer中
int length = socketChannel.read(buf);
数据写入到我们的Buffer中,我们就需要将他们读出来
buf.flip(); //转化为可读模式
byte[] data = new byte[length];
buf.get(data);
将数据从Buffer写入到Channel时
buf.clear();
byte[] resp = {'O','K'};
buf.put(resp);
buf.flip();//转换为读模式
socketChannel.write(buf);
这里为了方便直接使用原来的Buffer。
SocketChannel
作为客户端我们需要创建一个SocketChannel。
SocketChannel.open();
client.connect(new InetSocketAddress("127.0.0.1", 6060));
发送HELLO
给服务端
ByteBuffer buffer = ByteBuffer.allocate(10);
byte[] data = {'H', 'E', 'L', 'L', 'O'};
buffer.put(data);
buffer.flip();//转换为读模式
client.write(buffer);
阻塞等待读取数据
buffer.clear();
client.read(buffer);
buffer.flip();//转换为读模式
处理完成,需要关闭释放连接
//关闭客户端输入流
client.socket().shutdownInput();
//关闭客户端输出流
client.socket().shutdownOutput();
//关闭客户端socket时会关闭客户端channel
client.socket().close();
//关闭客户端channel,会同时关闭输入和输出流。
client.close();
关闭输出流会发送FIN包,若输入流未关闭仍然可以继续接收数据,这就是TCP的半连接。若处理完最后需要确保channel关闭。
FileChannel
FileChannel只能被FileInputStream、FileOutputStream、RandomAccessFile创建
RandomAccessFile
使用RandomAccessFile
创建FileChannel
//第一个参数时文件名,第二个参数是读写方式
RandomAccessFile randomAccessFile = new RandomAccessFile("1.txt","rw");
FileChannel channel = randomAccessFile.getChannel();
FileInputStream
使用RandomAccessFile
创建FileChannel
FileInputStream inputStream = new FileInputStream("1.txt");
channel = inputStream.getChannel();
inputStream获取的FileChannel只能读
FileOutputStream
使用RandomAccessFile
创建FileChannel
FileOutputStream outputStream = new FileOutputStream("1.txt");
channel = outputStream.getChannel();
inputStream获取的FileChannel只能写
关闭FileChannel
关闭FileChannel的方法和关闭SocketChannel方法一样。
//关闭channel时会关闭文件
channel.close();
//关闭文件时会关闭channel
randomAccessFile.close();
//关闭文件流时会关闭channel
inputStream.close();
//关闭文件流时会关闭channel
inputStream.close();
总结
由于源码解析的篇幅较长,因此将channel源码单独分出来讲解。
相关文献
微信扫一扫二维码关注订阅号杰哥技术分享
出处:https://www.cnblogs.com/Jack-Blog/p/12015516.html
作者:杰哥很忙
本文使用「CC BY 4.0」创作共享协议。欢迎转载,请在明显位置给出出处及链接。
NIO-Channel的更多相关文章
- Java NIO Channel和Buffer
Java NIO Channel和Buffer @author ixenos Channel和Buffer的关系 1.NIO速度的提高来自于所使用的结构更接近于OS执行I/O的方式:通道和缓冲器: 2 ...
- Java NIO Channel之FileChannel [ 转载 ]
Java NIO Channel之FileChannel [ 转载 ] @author zachary.guo 对于文件 I/O,最强大之处在于异步 I/O(asynchronous I/O),它允许 ...
- Java NIO Channel通道
原文链接:http://tutorials.jenkov.com/java-nio/channels.html Java NIO Channel通道和流非常相似,主要有以下几点区别: 通道可以读也可以 ...
- (三:NIO系列) Java NIO Channel
出处: Java NIO Channel 1.1. Java NIO Channel的特点 和老的OIO相比,通道和NIO流(非阻塞IO)主要有以下几点区别: (1)OIO流一般来说是单向的(只能读或 ...
- [翻译] java NIO Channel
原文地址:http://tutorials.jenkov.com/java-nio/channels.html JAVA NIO channels和流的概念很像,下面是他们的一些区别: 你可以对cha ...
- Java NIO Channel to Channel Transfers通道传输接口
原文链接:http://tutorials.jenkov.com/java-nio/channel-to-channel-transfers.html 在Java NIO中如果一个channel是Fi ...
- NIO Channel和Buffer
Java NIO 由以下几个核心部分组成: Buffer Channel Selector 传统的IO操作面向数据流,意味着每次从流中读一个或多个字节,直至完成,数据没有被缓存在任何地方.NIO操作面 ...
- Java NIO Channel to Channel Transfers
In Java NIO you can transfer data directly from one channel to another, if one of the channels is a ...
- NIO Channel的学习笔记总结
摘自:http://blog.csdn.net/tsyj810883979/article/details/6876603 1.1 非阻塞模式 Java NIO非堵塞应用通常适用用在I/O读写等方 ...
- NIO Channel Socket套接字相关Channel
阻塞非阻塞: NIO中的Channel主要分为两大类:一类是FileChannel,另一类是SocketChannel.NIO提供的核心非阻塞特性主要针对SocketChannel类,全部socket ...
随机推荐
- HTML知识点汇总
一.什么是HTML HTML是用来描述网页的一种语言. HTML是指超文本标记语言(不仅包含纯文本,还包含图片.超链接.音频.视频等). HTML使用一套标记标签来描述网页. 二.HTML标签的作用 ...
- p1156 题解(未完全解决)
题目描述 卡门――农夫约翰极其珍视的一条Holsteins奶牛――已经落了到“垃圾井”中.“垃圾井”是农夫们扔垃圾的地方,它的深度为D(2 \le D \le 100)D(2≤D≤100)英尺. 卡门 ...
- 「牛客练习赛53A」超越学姐爱字符串
更好的阅读体验 Portal Portal1: Nowcoder Description 超越学姐非常喜欢自己的名字,以至于英文字母她只喜欢\(\textrm{"c"}\)和\(\ ...
- 如何处理消息队列消费过程中的重复消息&如何实现幂等性
什么是幂等 幂等本来是数学上的概念,它的定义是这样的: 如果一个函数 f(x) 满足:f(f(x)) = f(x),则函数 f(x) 满足幂等性. 在计算机领域用来描述一个操作.方法或者服务.一个幂等 ...
- phpexcel导出数字带E的解决方法
phpexcel导出数字带E的解决方法 excel之所以带E 是因为按照数字格式来显示了(数字过长的时候) 数字左边或者右边加空格就变成字符串了 那么excel就会按照字符串格式来显示了 就不会带E了
- Python 面向对象之五 基础拾遗
Python 面向对象之五 基础拾遗 今天呢,就剩下的面向对象的相关知识进行学习,主要会学习以下几个方面的知识:1.上下文管理协议,2.为类加装饰器 3.元类 一.上下文管理协议 在学习文件操作的时候 ...
- C# 操作本地用户和组(基本全功能)
今天学习了下怎么用.Net操作本地用户和组,因为目前网上还没看到一篇比较完整的文章,所以整理了下也分享出来,最后附带参考文档,方便深究的童鞋继续学习.========== 原创作品 作者:Yo ...
- 你不知道的JS系列【1】- 什么是作用域
几乎所有的编程语言都能够储存变量,并且能在之后对这个变量值进行访问或修改,正是储存和访问变量的能力将状态带给了程序,那么,这些变量储存在哪里呢?程序需要时又是如何找到他们?这些问题说明需要一套设计 ...
- hdu 1251 统计难题 (字典树(Trie)<PS:C++提交不得爆内存>)
统计难题Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)Total Submis ...
- nyoj 22-素数求和问题(打表)
22-素数求和问题 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:41 submit:52 题目描述: 现在给你N个数(0<N<1000 ...