`
wangxuliangboy
  • 浏览: 210637 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

NIO实例

阅读更多


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实例

    在这个javaNIO实例中,我们可以学习到如何利用Java NIO进行文件的读取、写入以及复制操作。 首先,NIO的核心组件包括通道(Channels)、缓冲区(Buffers)和选择器(Selectors)。通道是数据传输的路径,如文件通道...

    Java NIO实例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java程序员提供了更高效、灵活的I/O操作方式。NIO与传统的 Blocking I/O(阻塞I/O)相比,主要的...

    Java高并发编程代码(Netty NIO 实例)

    本实例将深入探讨Netty如何实现NIO在高并发场景下的优化和应用。 首先,让我们理解Java的NIO(Non-blocking I/O,非阻塞I/O)。传统的Java IO模型(BIO)是基于流(Stream)的,对每一个连接都需要一个线程来处理,当...

    Java NIO实例UDP发送接收数据代码分享

    "Java NIO实例UDP发送接收数据代码分享" Java NIO(Non-blocking I/O)是一种异步I/O模型,允许开发者在单个线程中处理多个I/O操作,从而提高程序的性能和可扩展性。在Java NIO中,DatagramChannel是专门用于发送...

    java NIO实例

    Java NIO,全称为Non-Blocking Input/Output(非阻塞输入/输出),是Java从1.4版本开始引入的一种新的I/O模型,它为Java应用程序提供了更高效的数据传输方式。传统的Java I/O模型(BIO)在处理大量并发连接时效率较...

    NIO编程实现实例

    - 创建缓冲区:根据需要处理的数据类型创建对应的Buffer实例。 - 读写数据:使用通道与缓冲区交互,将数据从通道读入缓冲区,或者将缓冲区中的数据写入通道。 - 注册选择器:将通道注册到选择器,指定感兴趣的...

    java-nio.rar_java nio_nio 对象实例化

    在标题中提到的“java-nio.rar_java nio_nio 对象实例化”,我们可以理解为这个压缩包中包含了关于Java NIO对象实例化的具体示例或教程。下面我们将详细讨论NIO中的核心对象及其实例化方法。 1. **通道(Channel)*...

    nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio

    标题“nio.rar_NIO_NIO-socket_java nio_java 实例_java.nio”表明这个压缩包包含了一个关于Java NIO的实例,特别是关于NIO套接字(Socket)的编程示例。NIO套接字是Java 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客户端实例解析 #### 核心概念与原理 在深入解析这段代码之前,我们先来理解一下几个核心的概念:**多线程**、**NIO(Non-blocking I/O)**以及它们如何协同工作在客户端编程中。 - **多线程**:在...

    java NIO推送实例

    在这个实例中,"java NIO 消息推送实例" 旨在展示如何使用NIO进行服务器向客户端的消息推送。 1. **Java NIO基础** - **通道(Channels)**:Java NIO 提供了多种通道,如文件通道、套接字通道等,它们代表不同...

    socket通信NIO代理模式demo实例

    本实例"socket通信NIO代理模式demo"将展示如何利用NIO来构建一个高性能的代理服务器。 代理模式是一种设计模式,它允许我们创建一个代理对象来控制对原对象的访问。在NIO代理模式中,代理服务器作为客户端与目标...

    JavaNIO服务器实例Java开发Java经验技巧共6页

    本资料"JavaNIO服务器实例Java开发Java经验技巧共6页"可能是某个Java开发者或讲师分享的一份关于如何在Java中构建NIO服务器的教程,涵盖了6个关键页面的内容。尽管具体的细节无法在此直接提供,但我们可以根据Java ...

    Java NIO原理分析及代码实例

    Java NIO(New IO)是Java 1.4版本引入的一个新API,全称为Non-blocking Input/Output,它提供了一种不同于传统IO的编程模型,传统IO...在实际编码时,参考博文链接中的代码实例,可以帮助你更好地理解和实践Java NIO。

    一个NIO服务端,客户端的例子

    客户端则会创建Bootstrap实例,设置通道工厂,通常是NioSocketChannel。同样地,客户端也需要配置管道,其中包含一个ByteToMessageDecoder和一个ClientBusinessHandler,后者负责与服务器交互的逻辑。 在启动服务器...

    Nio详细介绍,实例演示

    NIO 详细介绍和实例演示 NIO(Non-blocking I/O)是 Java 提供的一种异步输入输出机制,允许开发者使用非阻塞的方式进行输入输出操作,从而提高了程序的性能和可扩展性。本文将对 NIO 进行详细的介绍,并提供实例...

    NIO与传统IO代码区别实例

    在Java编程领域,IO(Input/Output)和NIO(Non-blocking Input/Output)是两种不同的I/O模型,它们在处理数据输入和输出时有着显著的差异。本教程旨在帮助NIO初学者理解这两种模型的核心概念及其实际应用,通过具体...

    NIO 经典实例

    本实例将深入探讨NIO在服务器端和客户端的应用,通过`NioDemoServer.java`和`NioDemoClient.java`这两个文件来解析NIO的核心知识点。 1. **NIO基础** NIO的核心组件包括通道(Channels)、缓冲区(Buffers)和选择...

    NIO-实践-多线程实例

    NIO用于高性能Socket编程由来已久,网络也有较为丰富的原理和源代码。我这里主要介绍几点经验总结: 1.Selector.select()在筛选就绪的SelectionKey的时候,采用的是阻塞模式。同时只要在就绪的SelectionKey列表中有...

Global site tag (gtag.js) - Google Analytics