在Java NIO中用Channel来对程序与进行I/O操作主体的连接关系进行抽象,这些IO主体包括如文件、Socket或其他设备。简而言之,指代了一种与IO操作对象间的连接关系。

  按照Channel接口的定义,Channel只有open和closed两种状态,只有在channel处于open状态下对其操作时才有效,而对closed的channel进行操作会导致抛出异常。相应的Channel接口也仅有isOpen()和close()两种方法。

  在Socket编程中,常用的Channel类是ServerSocketChannel和SocketChannel。ServerSocketChannel表示作为Socket服务端,处于监听状态的Socket连接。而SocketChannel表示一个已经建立的Socket连接。

  ServerSocketChannel具有accept()方法,当该方法成功返回时,会返回一个已经建立的SocketChannle对象,这也表示了这两种代表不同状态的Socket Channel间的联系和区别。ServerSocketChannel通过bind()方法绑定到本地地址,并且可以通过setOption()方法设置SO_RCVBUF(Socket接收缓冲区大小)和SO_REUSEADDR(是否重用Socket地址,由于Socket在关闭时需要经过多个状态的变迁,这个选项通常在需要快速重启的场景下有用)两个Socket选项。

  SocketChannel采用connet()方法建立连接,并且支持非阻塞式建立,在非阻塞状态下连接的最终建立状态通过isConnetionPending()和finishConnect()进行组合判断。SocketChannel同时支持异步关闭,若写线程主动关闭了Channel,则并发的读操作将读取不到内容;若读线程主动关闭了Channel,则并发的写操作将得到AsynchronousCloseException。同样的对SocketChannle可以通过setOption()方法设置若干选项,包括:SO_SNDBUF(发送缓冲区), SO_RCVBUF, SO_KEEPALIVE(是否采用协议栈实现的保活机制,默认为FALSE), SO_REUSEADDR, SO_LINGER(阻塞式连接下的关闭等待时长), TCP_NODELAY(是否禁用Nagle算法)。

  这两个类涉及的相关类图如下图所示:

  可见,ServerSocketChannel和SocketChannel均继承了SelectableChannel以支持与Selector配合实现非阻塞式IO。SocketChannel继承了若干支持读写操作的Channel以支持读写操作。

  另外,Channel的读写需要借助于Buffer,可见在NIO中Buffer是程序中其他对象与Channel交互的中介,通过Buffer和Channel的配合实现对I/O对象的读写操作。

  几个关键的接口定义如下

  

public interface Channel {

	/**
* 判断是否开启
* @return
*/
public boolean isOpen(); public void close() throws IOException; } /**
* 可中断Channel</p>
* 1. 可被异步关闭. 若当前线程阻塞于Channel的读写操作,</l>
* 当另一线程调用close操作后,当前线程会收到一个AsynchronousCloseException</p>
*
* 2. 可中断. 若当前线程阻塞于Channel,当其他线程触发interrupt方法时</l>
* 会导致Channel Close,当前线程收到一个ClosedByInterruptException,
* 其interrupt状态被设置</p>
*
* 3. 若当前线程interrupt状态已被设置,当调用当前Channel的阻塞IO操作时,</l>
* channel会被close,线程会收到ClosedByInterruptException. </l>
* 其interrupt状态保持不变.</p>
*
* @author luojiahu
*
*/
public interface InterruptibleChannel extends Channel{ public void close() throws IOException; } /**
* 可读Byte Channel
* 可对当前Channel阻塞读. 若有其他线程正对当前Channel进行读操作,</l>
* 调用read会一直阻塞至其他上一读操作完成。
*
* @author luojiahu
*
*/
public interface ReadableByteChannel extends Channel { /**
* 从当前Channel中读取内容写入Buffer</l>
* 是否能够读入内容,取决于当前Channel的状态.</l>
* 如,对于一个非阻塞的Socket Channel,如果当前socket的</l>
* 接收缓冲区没有任何内容,则不能写入任何内容到src
* @param src
* @return
* @throws IOException
*/
public int read(ByteBuffer src) throws IOException; } /**
* 可写Byte Channel
* 可对当前Channel阻塞写.</l>
* @author luojiahu
*
*/
public interface WritableByteChannel extends Channel { /**
* 从dst buffer中读取内容写入当前Channel</l>
* 是否能够写入内容取决于当前Channel的状态</l>
* 如对于非阻塞 Socket Channel,只能写入不大于</l>
* 对应写入缓冲区可写大小的内容
*
* @param dst
* @throws IOException
*/
public void write(ByteBuffer dst) throws IOException; } /**
* 网络socket channel</l>
* @author luojiahu
*
*/
public interface NetWorkChannel extends Channel{ /**
* 绑定到本地地址</l>
* 一旦绑定,则绑定直至通道关闭</l>
* 如果参数未空,则绑定至自动分配的地址
* @param local
* @return
* @throws IOException
*/
NetWorkChannel bind(SocketAddress local) throws IOException; /**
* 获取绑定的本地地址
* @return
* @throws IOException
*/
SocketAddress getLocalAddress() throws IOException; /**
* 设定socket 选项
* @param name
* @param value
* @return
* @throws IOException
*/
<T> NetworkChannel setOption(SocketOption<T> name, T value) throws IOException; }

  

Java NIO 之 Socket Channel的更多相关文章

  1. 5. 彤哥说netty系列之Java NIO核心组件之Channel

    你好,我是彤哥,本篇是netty系列的第五篇. 简介 上一章我们一起学习了如何使用Java原生NIO实现群聊系统,这章我们一起来看看Java NIO的核心组件之一--Channel. 思维转变 首先, ...

  2. Java NIO学习笔记---Channel

    Java NIO 的核心组成部分: 1.Channels 2.Buffers 3.Selectors 我们首先来学习Channels(java.nio.channels): 通道 1)通道基础 通道( ...

  3. Java NIO之通道Channel

    channel与流的区别: 流基于字节,且读写为单向的. 通道基于快Buffer,可以异步读写.除了FileChannel之外都是双向的. channel的主要实现: FileChannel Data ...

  4. Java NIO中的Channel接口

    1. Channel  通道,可以将指定文件的部分或全部直接映射成Buffer. 不能直接读写Channel中的数据,Channel只能与ByteBuffer交互. 读数据时,把Channel中的数据 ...

  5. JAVA NIO 之Channel

    缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存.Channel 通道就是将数据传输给 ByteBuffer 对象或者从 ByteBuffer 对象获取数据进行传输. Channel 用于在 ...

  6. Java NIO学习系列二:Channel

    上文总结了Java NIO中的Buffer相关知识点,本文中我们来总结一下它的好兄弟:Channel.上文有说到,Java NIO中的Buffer一般和Channel配对使用,NIO中的所有IO都起始 ...

  7. Java NIO Channel 使用

    Java NIO 中的 Channel 分类: FileChannel SocketChannel ServerSocketChannel DatagramChannel channel 分类 Fil ...

  8. Java NIO 核心组件学习笔记

    背景知识 同步.异步.阻塞.非阻塞 首先,这几个概念非常容易搞混淆,但NIO中又有涉及,所以总结一下[1]. 同步:API调用返回时调用者就知道操作的结果如何了(实际读取/写入了多少字节). 异步:相 ...

  9. 3、谈谈 Java NIO

    在 JDK1.4 之后,为了提高 Java IO 的效率,Java 提供了一套 New IO (NIO),之所以称之为 New,原因在于它相对于之前的 IO 类库是新增的.此外,旧的 IO 类库提供的 ...

随机推荐

  1. 数据结构-堆(应用篇)之堆排序法-C和C++的实现

    堆排序 关于堆的内容我们已经在上一节中了解了,本节中将给出一个堆的应用-堆排序. 关于堆的概念可以看上一节,入口:http://www.cnblogs.com/HongYi-Liang/p/78536 ...

  2. 关于 " +new Date "

    关于 " +new Date " 的个人见解 今天晚上,在一个Javascript的Q群里,有人问下面这种代码是什么意思: var time = +new Date; 这段代码中, ...

  3. UVALive 3882 - And Then There Was One【约瑟夫问题】

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  4. Npm vs Yarn 之备忘大全

    有则笑话,如此讲到:"老丈人爱吃核桃,昨天买了二斤陪妻子送去,老丈人年轻时练过武,用手一拍核桃就碎了,笑着对我说:你还用锤子,你看我用手就成.我嘴一抽,来了句:人和动物最大的区别就是人会使用 ...

  5. 设置Sql server用户对表、视图、存储过程、架构的增删改查权限

    根据数据库Schema限制用户对数据库的操作行为 授予Shema dbo下对象的定义权限给某个用户(也就是说该用户可以修改架构dbo下所有表/视图/存储过程/函数的结构) use [Your DB N ...

  6. DFS算法(——模板习题与总结)

    首先,需要说明的是搜索算法本质上也是枚举的一种,时间复杂度还是很高的,遇到问题(特别是有水平的比赛上),不要优先使用搜索算法. 这里总结一下DFS算法: 1.从图中某个顶点出发,访问v. 2.找出刚访 ...

  7. 算法-java代码实现归并排序

    归并排序 对于一个int数组,请编写一个归并排序算法,对数组元素排序. 给定一个int数组A及数组的大小n,请返回排序后的数组. 测试样例: [1,2,3,5,2,3],6 [1,2,2,3,3,5] ...

  8. dedecms织梦自定义表单发送到邮箱-用163邮箱发送邮件

    https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=monline_3_dg&wd=dedecms 邮箱&oq=d ...

  9. Linux入门——用户组管理

    Linux用户组的管理 简介 用户组用来控制操作权限,防止无关人员莫名 rm -rf 重要文件,导致文件无法恢复或者花费很大代价恢复,这不是一个系统管理员 想看到的结果,所以一般系统管理员都会给开发人 ...

  10. MYSQL ORDER BY Optimization

    ORDER BY Optimization 某些情况下,MYSQL可以使用index排序而避免额外的sorting. 即使order by语句列不能准确的匹配index,只要没有index中(不在or ...