No-Block
和Block
IO
的区别:
一个典型的网络通讯步骤为: open
(新建socket Chanel
)-->
connect(
尝试建立连接)
-->
accept(
连接被接受)
-->
read(
读取请求)
send
(输出结果)-->
close(
连接关闭)
。
对于一个No-Block
的网络IO
,上面的每一步都是会马上返回的,当然返回的结果可能为null
,可能不为null
,这个要看下上文(context
)决定。一般情况下,我们都是需要不为null
的结果,这个就需要我们在适当的时机,执行适当的步骤,这样就会得到我们想要的结果。何为适当的时机?这个下面会讲。
对于一个block
的网络IO
,上面的每一步执行的时候,如果没到适当的时机,当前线程就会被block
住,直到适当的时机,返回给你确定的结果。
当然对与No-Block
或者Block IO
,上面的每一步都有可能会抛出IOException
异常的。
NIO
编程接触的几个关键概念:
Buffer
:是一块连续的内存块,是 NIO
数据读或写的中转地。Buffer
这篇blog
暂时略过不讲。
Chanel
:数据的源头或者数据的目的地,用于向 buffer
提供数据或者读取 buffer
数据 ,异步 I/O
支持。
注意chanel
有2
类,一种叫SocketChanel,
一种叫ServerSocketChanel
,看名字我们就知道,一类是普通的socket chanel
,client
端和服务器端都用的,一类是专门用在server
端的。当然这个界限也不是绝对的,互为client
和server
的情况也是存在的。
Selector
:
chanel
事件的侦听者,
它能检测一个或多个通道
(channel)
上的事件,并将事件分发出去。使用一个
select
线程就能监听多个通道上的事件,并基于事件驱动触发相应的响应。
SelectionKey
:
chanel
上发生的事件,
包含了事件的状态信息和时间以及对应的
chanel
。
Chanel
的状态:
可连(
Connectable
):当一个
Chanel
完成
socket
连接操作已完成或者已失败放弃时
能连(
Acceptable
):当一个
Chanel
已经准备好接受一个新的
socket
连接时
可读(
Readable
):当一个
Chanel
能被读时
可写(
Writable
):当一个
Chanel
能被写时
结合对照上面的网络通讯步骤我们可以有以下推导出的结论:
当一个
Server Chanel
是
Connectable
时,
client
端尝试
connect
才会成功。
当一个
Server
Chanel
是
Acceptable
时,
client
的连接请求被真正受理,一个新的
chanel
会被生成,并且记录了
localAdrress
和
remoteAddress.
为进一步读写做准备。
当一个
Chanel
是
Readable
时,我们从这个
Chanel
中读取数据才会成功。
当一个
Chanel
是
Writable
时,我们往这个
Chanel
中写数据才会成功。
记住一点,对于一个
No-Block
的
Chanel
来说,上面
4
个操作都会马上返回或者抛出
IOException
,但是是不是成功就难说了,前面就说了,我们在一个
Chanel
做操作的时候,我们要密切关注
Chanel
的当前状态。只有在知道
Chanel
的当前状态时,我们才能在这个
Chanel
上做最适当的操作。
聪明的你可能马上就会想到,要是你操作的
Chanel
的状态的转换信息能被你抓取,这些问题就迎刃而解了。对啦,
NIO
就是这样设计的。一个
Chanel
可以注册一个
Selector
(就像一个事件侦听器),而且你还要告知你想要要侦听的状态。用一段代码来说明下:
selector =
SelectorProvider.provider().openSelector();
serverChannel1 =
ServerSocketChannel.open();
serverChannel1.configureBlocking(false);
InetSocketAddress isa = new
InetSocketAddress("localhost", 9999);
serverChannel1.socket().bind(isa);
serverChannel1.register(selector,
SelectionKey.OP_ACCEPT);
这段代码的意思就是我们打开了一个
ServerChanel
,侦听本机的
9999
端口,并且新建了一个
Selector,
然后这个
ServerChanel
注册了这个
Selector
,并且指定了它感兴趣的状态类型是
OP_ACCEPT.
这样有什么效果呢?
注意红色那句,这句意思是selector要求serverChannel1状态为acceptable的时候把这个消息告诉selector.
效果就是:
当这个
ServerChanel
状态为
Acceptable
时,
Selector
就会收到一个消息,这个消息当然就是一个
SelectionKey
对象。调用
Selector
的
selectedKeys
()方法,我们就能得到所有
Chanel
发送过来的消息。
因为
SelectionKey
包含
事件的状态,时间以及对应的
Chanel
,很自然的,我们遍历这个
Set<SelectionKey>,
根据
SelectionKey
的状态,就能在相应的
Chanel
做正确的操作。比如,能读的时候我们就读,能写的时候我们就写。
最后讲讲
Server
端和
Client
编程的一般步骤:
对于
Client
来一般是这样的:
InetSocketAddress isa = new InetSocketAddress(host,
port);
SocketChannel sc = null;
sc = SocketChannel.open();
sc.connect(isa);
sc.write(data);
…
Sc.read(buff);
构造一个
InetSocketAddress
对象
-->
open
-->
connect
-->
write
-->
read
注意这里用的不是
No-Block
的方式,因为
client
如果没有得到
server
端的正确回应的话就采取下一步操作无疑是没有意义的。
Server
端:
selector
= SelectorProvider.provider
().openSelector();
serverChannel
= ServerSocketChannel.open
();
serverChannel
.configureBlocking(
false
);
InetSocketAddress isa =
new
InetSocketAddress(
"localhost"
,
9999
);
serverChannel
.socket().bind(isa);
serverChannel
.register(
selector
, SelectionKey.
OP_ACCEPT
);
构造一个
Selector
-->
打开一个
serverSocketChanel
-->
设定
serverSocketChanel
为
no-block-->
bind serverSocketChanel
到一个
host
和
port
-->
register Selector
并告知感兴趣的状态类型转换。
在
SelectionKey
Set
上遍历操作:
while (true) {
selector.select();
Iterator selectedKeys =
this.selector.selectedKeys().iterator();
while
(selectedKeys.hasNext()) {
SelectionKey key = (SelectionKey)
selectedKeys.next();
selectedKeys.remove();
if (!key.isValid()) {
continue;
}
if (key.isAcceptable()) {
accept(key);
} else if (key.isReadable()) {
read(key);
} else if (key.isWritable()) {
write(key);
}
}
}
在这个循环里面我们会根据
SelectionKey
的状态,采取不同的操作的。当连接被
accepted
时,
一个新的
chanel
会被生成,并且记录了
localAdrress
和
remoteAddress.
为进一步读写做准备。
accept
函数如下:
public void accept(SelectionKey key) throws
IOException {
ServerSocketChannel serverSocketChannel = (ServerSocketChannel)
key.channel();
SocketChanel socketChannel1 = serverSocketChannel.accept();
socketChannel1.configureBlocking(false);
socketChannel1.register(selector, SelectionKey.OP_READ);
}
这里新的
Chanel
被构建,最后同样会注册到
selector
,
同时要求当这个
Chanel
为
Readable
时,一个
SelectionKey
被放入到
Selector
中。这样上面循环会用
read(key)
来处理这个
SelectionKey.
分享到:
相关推荐
我研究并实现的Java Nio selector例子。java侧起server(NioUdpServer1.java),基于Java Nio的selector 阻塞等候,一个android app(NioUdpClient1文件夹)和一个java程序(UI.java)作为两个client分别向该server...
Java NIO(New IO)是Java 1.4版本引入的一个新模块,它提供了一种不同于传统IO(基于字节流和字符流)的I/O操作方式。传统的IO模型是阻塞式的,而NIO的核心...请务必仔细研究并实践这些示例,以深化你的Java NIO知识。
NIO(New IO)是Java平台中用于处理输入/输出操作的一种高级API,它在Java 1.4版本中引入,以替代传统的IO流模型。NIO提供了更高效、更灵活的数据传输方式...建议读者下载并仔细研究,以便更好地利用NIO提升程序性能。
### 基于Java NIO的非阻塞通信的研究与实现 #### 摘要 本文探讨了Java NIO(New I/O)框架中的非阻塞通信机制,并对其原理及应用进行了深入研究。NIO是一种现代I/O处理方法,通过引入缓冲区、通道和选择器等新概念...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种I/O模型,旨在提供一种更高效、更具控制力的I/O操作方式。与传统的-blocking I/O(阻塞I/O)相比,NIO的关键在于它...
Java Socket和NIO(Non-blocking Input/Output,非阻塞I/O)是Java网络编程中的重要组成部分,它们在处理高并发、低延迟的网络服务时展现出强大的能力。本篇文章将深入探讨这两个概念,并通过示例代码`...
Java NIO(非阻塞I/O)和AIO(异步I/O)是Java平台中用于提高I/O性能的重要技术。...通过研究这些代码和文档,开发者可以学习如何创建基于NIO和AIO的服务器,如何处理并发连接,以及如何优化性能。
综上所述,“Large-File-Processing-master_javanio_java大文件处理_”项目涵盖了Java NIO在大文件处理中的核心技术和最佳实践,是学习和研究Java高效处理大文件的宝贵资源。通过深入理解这些知识点,并结合项目中的...
Java Socket编程是网络通信的核心部分,它提供了进程间通信(IPC)的能力,使得运行在不同设备上的应用程序可以通过网络...在压缩包中的"Socket"文件可能包含了具体的BIO和NIO的Java实现示例,可以进一步学习和研究。
Java NIO,全称为New Input/Output,是Java在1.4版本引入的一个新特性,用以替代传统的IO模型。...通过深入研究和分析这个项目,开发者能够更好地掌握NIO在实际项目中的应用,提升系统性能和稳定性。
Java NIO(New IO)是Java 1.4版本引入的一个新特性,全称为Non-blocking Input/Output,即非阻塞I/O。...对于想要深入理解Java NIO或想自己动手搭建服务器的开发者来说,这是一个值得研究的项目。
Java.nio,全称为Java Non-blocking Input/...而压缩包中的"thread"、"noblock"、"block"可能分别对应于线程管理、非阻塞I/O和阻塞I/O的相关示例或讨论,进一步深入研究这些内容,有助于深化对Java.nio的理解和应用。
基于Java NIO的高校心理咨询系统的研究与设计.pdf
#资源达人分享计划# java nio从入门到精通的代码详解 主要结合博文进行学习 详情可配合我的博客进行学习 https://blog.csdn.net/weixin_47872288/article/details/120342049
### 基于Java NIO开发高性能并发型服务器程序的研究 #### 一、引言 在互联网技术迅速发展的背景下,服务器程序面临着越来越高的并发访问需求。为了满足这一需求,传统阻塞型网络I/O(Input/Output)逐渐暴露出其在...
通过研究这些源码,开发者不仅可以了解NIO的工作原理,还可以学习到如何更高效地利用Java平台的特性来优化应用程序,这对于提升代码质量和性能至关重要。此外,JDK 1.6的源码也对后续版本的Java NIO改进和增强提供了...