资讯专栏INFORMATION COLUMN

java NIO

AlphaWatch / 754人阅读

摘要:是什么就不在此文展开,这篇主要来介绍下我们要怎样通过来构建一个服务客户端程序的。的通信完全依赖与,数据的写入和读取都是通过从中写入读取。和上的调用一样的功能,监听已经注册在上面的文件描述符,监听上的事件。

NIO是什么就不在此文展开,这篇主要来介绍下我们要怎样通过java NIO来构建一个服务客户端程序的。

0x01 涉及知识点

NIO建立一个服务端和客户端程序主要涉及的知识点有:

channel

selector

buffer

如果通过C/C++写过通信程序的应该知道都是通过linux提供的系统调用来完成,java NIO的实现思想上没有什么变化只是在实现方式上换了一种新的概念,并提供了更友好的开发模式供开发人员更加简便快捷的来实现自己想要的功能。

channel:NIO的通信完全依赖与channel,数据的写入和读取都是通过channel从buffer中写入/读取。

selector:和linux上的select调用一样的功能,监听已经注册在上面的socket文件描述符,java NIO监听channel上的事件。主要有:OP_CONNECT()、OP_ACCEPT、OP_READ、OP_WRITE。

buffer主要是从channel中读出数据或者写入数据到channel。

0x02 server
public class NioServer {

    public static void main(String[] args) {
        try {
            // 建立一个serversocketchannel,用于监听是否有连接到来
            ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
            // 设置为非阻塞模式
            serverSocketChannel.configureBlocking(false);
            // 绑定监听的地址
            serverSocketChannel.bind(new InetSocketAddress(8080));
            // 获取一个selector
            Selector selector = Selector.open();
            // 将channel注册到selector中,并且这个channel关心的是accept事件
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

            while(true) {
                int readySize = selector.select();
                if(readySize == 0) {
                    continue;
                }
                // 获取有事件到来的selectKeys
                Set selectionKeys = selector.selectedKeys();
                // 处理到来的事件
                for(Iterator iter = selectionKeys.iterator(); iter.hasNext(); ) {
                    SelectionKey selectionKey = iter.next();
                    // 要将已经被处理的selectionKey删除掉
                    iter.remove();
                    if(selectionKey.isAcceptable()) {
                        System.out.println("acceptable");
                        ServerSocketChannel listenChannel = (ServerSocketChannel) selectionKey.channel();
                        /* 获取连接进来的channel */
                        SocketChannel socketChannel = listenChannel.accept();
                        socketChannel.configureBlocking(false);
                        socketChannel.write(ByteBuffer.wrap(new String("java NIO").getBytes()));
                        socketChannel.register(selector, SelectionKey.OP_READ);
                    } else if(selectionKey.isReadable()) {
                        SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                        ByteBuffer byteBuffer = ByteBuffer.allocate(100);
                        int readSize = socketChannel.read(byteBuffer);
                        /* 相应的channel连接断开了将其关闭掉 */
                        if(readSize == -1) {
                            socketChannel.close();
                            selectionKey.cancel();
                            continue;
                        }
                        /* 将客户端写入的数据显示出来 */
                        byte[] bytes = byteBuffer.array();
                        String message = new String(bytes).trim();
                        System.out.println(message);
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
}
0x03 client
public class NioClient {

    public static void main(String[] args) {
        SocketChannel socketChannel = null;
        try {
            socketChannel = SocketChannel.open();
            socketChannel.configureBlocking(false);
            // 发起连接请求
            socketChannel.connect(new InetSocketAddress("127.0.0.1", 8080));
            Selector selector = Selector.open();
            socketChannel.register(selector, SelectionKey.OP_CONNECT);
            while (true) {
                int readySize = selector.select();
                if(readySize == 0) {
                    continue;
                }
                Set selectionKeys =  selector.selectedKeys();
                for(SelectionKey selectionKey : selectionKeys) {
                    SocketChannel clientChannel = (SocketChannel)selectionKey.channel();
                    if(selectionKey.isConnectable()) {
                        /* 连接还没建立完全,等待连接建立完成 */
                        if(clientChannel.isConnectionPending()) {
                            clientChannel.finishConnect();
                        }
                        clientChannel.register(selector, SelectionKey.OP_READ);
                    } else if (selectionKey.isReadable()) {
                        System.out.println("readable");
                        ByteBuffer byteBuffer = ByteBuffer.allocate(100);
                        System.out.println(clientChannel.read(byteBuffer));
                        byte[] bytes = byteBuffer.array();
                        String message = new String(bytes).trim();
                        System.out.println(message);
                    }
                    selectionKeys.remove(selectionKey);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }
}
0x04 参考

NIO相关的概念可以点这里

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/66220.html

相关文章

  • Java NIO 系列教程

    摘要:异步可以让你异步的使用,例如当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。因此,单个的线程可以监听多个数据通道。下面是系列文章的目录概述通道之间的数据传输与原文译者郭蕾校对方腾飞 Java NIO(New IO)是一个可以替代标准Java IO API的IO API(从Java 1.4开始),Java NIO提供了与标准IO不同的...

    fanux 评论0 收藏0
  • Java NIO 概览

    摘要:线程之间的切换对于操作系统来说是昂贵的。因此,单线程可以监视多个通道中的数据。当方法返回后,线程可以处理这些事件。 一 NIO简介 Java NIO 是 java 1.4 之后新出的一套IO接口,这里的的新是相对于原有标准的Java IO和Java Networking接口。NIO提供了一种完全不同的操作方式。 NIO中的N可以理解为Non-blocking,不单纯是New。 它支持面...

    chemzqm 评论0 收藏0
  • 关于Java IO与NIO知识都在这里

    摘要:从通道进行数据写入创建一个缓冲区,填充数据,并要求通道写入数据。三之通道主要内容通道介绍通常来说中的所有都是从通道开始的。从中选择选择器维护注册过的通道的集合,并且这种注册关系都被封装在当中停止选择的方法方法和方法。 由于内容比较多,我下面放的一部分是我更新在我的微信公众号上的链接,微信排版比较好看,更加利于阅读。每一篇文章下面我都把文章的主要内容给列出来了,便于大家学习与回顾。 Ja...

    Riddler 评论0 收藏0
  • Java NIO 的前生今世 之一 简介

    摘要:简介是由引进的异步由以下几个核心部分组成和的对比和的区别主要体现在三个方面基于流而基于操作是阻塞的而操作是非阻塞的没有概念而有概念基于与基于传统的是面向字节流或字符流的而在中我们抛弃了传统的流而是引入了和的概念在中我只能从中读取数据到中或将 简介 Java NIO 是由 Java 1.4 引进的异步 IO.Java NIO 由以下几个核心部分组成: Channel Buffer Se...

    李义 评论0 收藏0
  • 动力节点JavaNIO教程,轻松攻破Java NIO技术壁垒

    摘要:学习和掌握技术已经不是一个攻城狮的加分技能,而是一个必备技能。是双向的,不仅可以读取数据还能保存数据,程序不能直接读写通道,只与缓冲区交互为了让大家不被高并发与大量连接处理问题所困扰,动力节点推出了高效处理模型应用教程。 大家肯定了解Java IO, 但是对于NIO一般是陌生的,而现在使用到NIO的场景越来越多,很多技术框...

    ralap 评论0 收藏0
  • Netty序章之BIO NIO AIO演变

    摘要:后改良为用线程池的方式代替新增线程,被称为伪异步。最大的问题是阻塞,同步。每次请求都由程序执行并返回,这是同步的缺陷。这些都会被注册在多路复用器上。多路复用器提供选择已经就绪状态任务的能力。并没有采用的多路复用器,而是使用异步通道的概念。 Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能、高可靠的网络服务器和客户端程序。Netty简化了网络程序的开发,是很多框架和公司...

    VincentFF 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<