import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
/**
* 通过ServerSocketChannel.open()获得一个Server的Channel对象。 通过Selector.open()来获得一个Selector对象。
* 从Server的Channel对象上可以获得一个Server的Socket,并让它在80端口监听。
* 通过ServerSocketChannel.configureBlocking(false)可以将当前的Channel配置成异步非阻塞的方式。如果没有这一步,那么Channel默认的方式跟传统的一样,是阻塞式的。
* 将当前的Channel注册到Selector对象中去,并告诉Selector当前的Channel关心的操作是OP_ACCEPT,也就是当有新的请求的时候,Selector负责更新此Channel的状态。
* 在循环当中调用selector.select(),如果当前没有任何新的请求过来,并且原来的连接也没有新的请求数据到达,这个方法会阻塞住,一直等到新的请求数据过来为止。
* 如果当前都请求的数据到达,那么selector.select()就会立刻退出,这时候可以从selector.selectedKeys()获得所有在当前selector注册过的并且有数据到达的这些Channel的信息(SelectionKey)。
* 遍历所有的这些SelectionKey来获得相关的信息。如果某个SelectionKey的操作是OP_ACCEPT,也就是isAcceptable,那么可以判定这是那个Server Channel,并且是有新的连接请求到达了。
* 当有新的请求来的时候,通过accept()方法可以获得新的channel服务于这个新来的请求。然后通过configureBlocking(false)可以将当前的Channel配置成异步非阻塞的方式。
* 接着将这个新的channel也注册到selector中,并告诉Selector当前的Channel关心的操作是OP_READ,也就是当前Channel有新的数据到达的时候,Selector负责更新此Channel的状态。
* 如果在循环当中发现某个SelectionKey的操作是OP_READ,也就是isReadable,那么可以判定这不是那个Server
* Channel,而是在循环内部注册的连接Channel,表明当前SelectionKey对应的这个Channel有数据到达了。
* 有数据到达之后的处理方式是下面要详细讨论的问题,在这里,我们简单地用一个方法readDataFromSocket(key)来表示,功能就是从这个Channel中读取数据。
*
* @author Administrator
*/
public class NIOSocketServer {
public static void main(String[] argv) throws Exception {
// 可以通过配套这个参数来选择自己的selector -Djava.nio.channels.spi.SelectorProvider=
System.out.println(System.getProperty("java.nio.channels.spi.SelectorProvider"));
ServerSocketChannel serverCh = ServerSocketChannel.open();
System.out.println(serverCh);
// 通过调用此类的 open 方法创建选择器,该方法将使用系统的默认选择器提供程序创建新的选择器。也可通过调用自定义选择器提供程序的 openSelector 方法来创建选择器。通过选择器的 close
// 方法关闭选择器之前,它一直保持打开状态。
Selector selector = Selector.open();
ServerSocket serverSocket = serverCh.socket();
serverSocket.bind(new InetSocketAddress(800));
serverCh.configureBlocking(false);
serverCh.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
// 则在 Selector.select()上就会始终有事件出现,CPU就一直处理了,而此时select()应该是阻塞的。
selector.select();
Iterator it = selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
if (key.isAcceptable()) {
ServerSocketChannel server = (ServerSocketChannel) key.channel();
System.out.println(key);
SocketChannel channel = server.accept();
channel.configureBlocking(false);
// 接着将这个新的channel也注册到selector中,并告诉Selector当前的Channel关心的操作是OP_READ,OP_WRITE
channel.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
// System.out.println(key.isWritable());
if (key.isReadable()) {
SocketChannel sChannel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
sChannel.read(buffer);
buffer = (ByteBuffer) buffer.flip();
byte[] b = new byte[buffer.limit()];
buffer.get(b);
System.out.println(new String(b));
// sChannel.configureBlocking(true);
// System.out.println(new String(buffer.duplicate().array()));
buffer.clear();
buffer.put("<html><body>hello</body></html>".getBytes());
buffer.flip();
sChannel.write(buffer);
// 关闭此通道。否则会出现死循环
sChannel.close();
// sChannel.finishConnect();
// System.out.println(sChannel.isConnected());
}
// else if (key.isWritable()) {
// SocketChannel sChannel = (SocketChannel) key.channel();
// // sChannel.configureBlocking(true);
// ByteBuffer buffer = ByteBuffer.allocate(100);
// buffer.put("<html><body>hello</body></html>".getBytes());
// buffer.flip();
// sChannel.write(buffer);
// sChannel.close();
// // sChannel.finishConnect();
// // System.out.println(sChannel.isConnected());
// }
it.remove();
}
}
}
}
分享到:
相关推荐
在这个javaNIO实例中,我们可以学习到如何利用Java NIO进行文件的读取、写入以及复制操作。 首先,NIO的核心组件包括通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。通道是数据传输的路径,如文件通道...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java程序员提供了更高效、灵活的I/O操作方式。NIO与传统的 Blocking I/O(阻塞I/O)相比,主要的...
本实例将深入探讨Netty如何实现NIO在高并发场景下的优化和应用。 首先,让我们理解Java的NIO(Non-blocking I/O,非阻塞I/O)。传统的Java IO模型(BIO)是基于流(Stream)的,对每一个连接都需要一个线程来处理,当...
"Java NIO实例UDP发送接收数据代码分享" Java NIO(Non-blocking I/O)是一种异步I/O模型,允许开发者在单个线程中处理多个I/O操作,从而提高程序的性能和可扩展性。在Java NIO中,DatagramChannel是专门用于发送...
Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输方式。传统的Java I/O模型(BIO)在处理大量并发连接时效率较...
- 创建缓冲区:根据需要处理的数据类型创建对应的Buffer实例。 - 读写数据:使用通道与缓冲区交互,将数据从通道读入缓冲区,或者将缓冲区中的数据写入通道。 - 注册选择器:将通道注册到选择器,指定感兴趣的...
在标题中提到的“java-nio.rar_java nio_nio 对象实例化”,我们可以理解为这个压缩包中包含了关于Java NIO对象实例化的具体示例或教程。下面我们将详细讨论NIO中的核心对象及其实例化方法。 1. **通道(Channel)*...
标题“nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio”表明这个压缩包包含了一个关于Java NIO的实例,特别是关于NIO套接字(Socket)的编程示例。NIO套接字是Java NIO库中用于网络通信的关键组件,它们允许...
**JAVA-NIO程序设计完整实例** Java NIO(New IO)是Java 1.4引入的一个新特性,它为Java提供了非阻塞I/O操作的能力,使得Java在处理I/O时更加高效。NIO与传统的BIO(Blocking I/O)模型相比,其核心在于它允许程序...
### 多线程NIO客户端实例解析 #### 核心概念与原理 在深入解析这段代码之前,我们先来理解一下几个核心的概念:**多线程**、**NIO(Non-blocking I/O)**以及它们如何协同工作在客户端编程中。 - **多线程**:在...
在这个实例中,"java NIO 消息推送实例" 旨在展示如何使用NIO进行服务器向客户端的消息推送。 1. **Java NIO基础** - **通道(Channels)**:Java NIO 提供了多种通道,如文件通道、套接字通道等,它们代表不同...
本实例"socket通信NIO代理模式demo"将展示如何利用NIO来构建一个高性能的代理服务器。 代理模式是一种设计模式,它允许我们创建一个代理对象来控制对原对象的访问。在NIO代理模式中,代理服务器作为客户端与目标...
本资料"JavaNIO服务器实例Java开发Java经验技巧共6页"可能是某个Java开发者或讲师分享的一份关于如何在Java中构建NIO服务器的教程,涵盖了6个关键页面的内容。尽管具体的细节无法在此直接提供,但我们可以根据Java ...
Java NIO(New IO)是Java 1.4版本引入的一个新API,全称为Non-blocking Input/Output,它提供了一种不同于传统IO的编程模型,传统IO...在实际编码时,参考博文链接中的代码实例,可以帮助你更好地理解和实践Java NIO。
客户端则会创建Bootstrap实例,设置通道工厂,通常是NioSocketChannel。同样地,客户端也需要配置管道,其中包含一个ByteToMessageDecoder和一个ClientBusinessHandler,后者负责与服务器交互的逻辑。 在启动服务器...
NIO 详细介绍和实例演示 NIO(Non-blocking I/O)是 Java 提供的一种异步输入输出机制,允许开发者使用非阻塞的方式进行输入输出操作,从而提高了程序的性能和可扩展性。本文将对 NIO 进行详细的介绍,并提供实例...
在Java编程领域,IO(Input/Output)和NIO(Non-blocking Input/Output)是两种不同的I/O模型,它们在处理数据输入和输出时有着显著的差异。本教程旨在帮助NIO初学者理解这两种模型的核心概念及其实际应用,通过具体...
本实例将深入探讨NIO在服务器端和客户端的应用,通过`NioDemoServer.java`和`NioDemoClient.java`这两个文件来解析NIO的核心知识点。 1. **NIO基础** NIO的核心组件包括通道(Channels)、缓冲区(Buffers)和选择...
NIO用于高性能Socket编程由来已久,网络也有较为丰富的原理和源代码。我这里主要介绍几点经验总结: 1.Selector.select()在筛选就绪的SelectionKey的时候,采用的是阻塞模式。同时只要在就绪的SelectionKey列表中有...