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)的功能,通过引入SourceChannelSinkChannel实现,底层实际还是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源码单独分出来讲解。

相关文献

  1. SCTP协议详解
  2. 史上最强Java NIO入门:担心从入门到放弃的,请读这篇!
  3. Java NIO系列教程



微信扫一扫二维码关注订阅号杰哥技术分享

出处:https://www.cnblogs.com/Jack-Blog/p/12015516.html

作者:杰哥很忙

本文使用「CC BY 4.0」创作共享协议。欢迎转载,请在明显位置给出出处及链接。

NIO-Channel的更多相关文章

  1. Java NIO Channel和Buffer

    Java NIO Channel和Buffer @author ixenos Channel和Buffer的关系 1.NIO速度的提高来自于所使用的结构更接近于OS执行I/O的方式:通道和缓冲器: 2 ...

  2. Java NIO Channel之FileChannel [ 转载 ]

    Java NIO Channel之FileChannel [ 转载 ] @author zachary.guo 对于文件 I/O,最强大之处在于异步 I/O(asynchronous I/O),它允许 ...

  3. Java NIO Channel通道

    原文链接:http://tutorials.jenkov.com/java-nio/channels.html Java NIO Channel通道和流非常相似,主要有以下几点区别: 通道可以读也可以 ...

  4. (三:NIO系列) Java NIO Channel

    出处: Java NIO Channel 1.1. Java NIO Channel的特点 和老的OIO相比,通道和NIO流(非阻塞IO)主要有以下几点区别: (1)OIO流一般来说是单向的(只能读或 ...

  5. [翻译] java NIO Channel

    原文地址:http://tutorials.jenkov.com/java-nio/channels.html JAVA NIO channels和流的概念很像,下面是他们的一些区别: 你可以对cha ...

  6. Java NIO Channel to Channel Transfers通道传输接口

    原文链接:http://tutorials.jenkov.com/java-nio/channel-to-channel-transfers.html 在Java NIO中如果一个channel是Fi ...

  7. NIO Channel和Buffer

    Java NIO 由以下几个核心部分组成: Buffer Channel Selector 传统的IO操作面向数据流,意味着每次从流中读一个或多个字节,直至完成,数据没有被缓存在任何地方.NIO操作面 ...

  8. 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 ...

  9. NIO Channel的学习笔记总结

    摘自:http://blog.csdn.net/tsyj810883979/article/details/6876603 1.1  非阻塞模式 Java  NIO非堵塞应用通常适用用在I/O读写等方 ...

  10. NIO Channel Socket套接字相关Channel

    阻塞非阻塞: NIO中的Channel主要分为两大类:一类是FileChannel,另一类是SocketChannel.NIO提供的核心非阻塞特性主要针对SocketChannel类,全部socket ...

随机推荐

  1. 搞清楚 Python 的迭代器、可迭代对象、生成器

    很多伙伴对 Python 的迭代器.可迭代对象.生成器这几个概念有点搞不清楚,我来说说我的理解,希望对需要的朋友有所帮助. 1 迭代器协议 迭代器协议是核心,搞懂了这个,上面的几个概念也就很好理解了. ...

  2. 精心整理(含图版)|你要的全拿走!(R数据分析,可视化,生信实战)

    本文首发于“生信补给站”公众号,https://mp.weixin.qq.com/s/ZEjaxDifNATeV8fO4krOIQ更多关于R语言,ggplot2绘图,生信分析的内容,敬请关注小号. 为 ...

  3. Python脚本之——API自动化框架总结

    学完了Python脚本接口自动化之后,一直没有对该框架做总结,今天终于试着来做一份总结了. 框架结构如下图: 来说一下每个目录的作用: Configs:该目录下存放的是.conf,.ini文件格式的配 ...

  4. Appium+python自动化(四十)-Appium自动化测试框架综合实践 - 代码实现(超详解)

    1.简介 今天我们紧接着上一篇继续分享Appium自动化测试框架综合实践 - 代码实现.由于时间的关系,宏哥这里用代码给小伙伴演示两个模块:注册和登录. 2.业务模块封装 因为现在各种APP的层出不群 ...

  5. 网站搭建-2-本地网站搭建-安装Linux虚拟机/ 安装IIS Windows

    搭建网站-1-域名申请参见公众号 生物信息系统(swxxxt) 首先,已经拥有了一个可以正常使用的域名. 之前买了两年的阿里的服务器,由于是Windows的,最后不了了之了(因为当时找的代码都是lin ...

  6. [LC] 700题 Search in a Binary Search Tree (二叉搜索树中的搜索) (二叉搜索树)

    ①中文题目 给定二叉搜索树(BST)的根节点和一个值. 你需要在BST中找到节点值等于给定值的节点. 返回以该节点为根的子树. 如果节点不存在,则返回 NULL. 例如, 给定二叉搜索树: 在上述示例 ...

  7. [LC]206题 Reverse Linked List (反转链表)(链表)

    ①英文题目 Reverse a singly linked list. Example: Input: 1->2->3->4->5->NULL Output: 5-> ...

  8. Spring框架学习笔记(7)——Spring Boot 实现上传和下载

    最近忙着都没时间写博客了,做了个项目,实现了下载功能,没用到上传,写这篇文章也是顺便参考学习了如何实现上传,上传和下载做一篇笔记吧 下载 主要有下面的两种方式: 通过ResponseEntity实现 ...

  9. nyoj 40-公约数和公倍数(gcd)

    40-公约数和公倍数 内存限制:64MB 时间限制:1000ms Special Judge: No accepted:30 submit:47 题目描述: 小明被一个问题给难住了,现在需要你帮帮忙. ...

  10. 用安全密钥验证ssh

    1.需要打开两台虚拟机,并保证两台虚拟机可以ping通: 本地主机IP:192.168.8.120 远程主机IP:192.168.8.100 2.在本地主机生成密钥对,输入命令“ssh-keygen” ...