`
wangqisen
  • 浏览: 46793 次
文章分类
社区版块
存档分类
最新评论

多路复用I/O

 
阅读更多

套接字通道

在套接字通道方面的改进是提供了对非阻塞I/O和多路复用I/O的支持。传统的流的I/O操作是阻塞式的。在进行I/O操作的时候,线程会处于阻塞状态等待操作完成。NIO中引入了非阻塞I/O的支持,不过只限于套接字I/O操作。所有继承自SelectableChannel的通道类都可以通过configureBlocking方法来设置是否采用非阻塞模式。在非阻塞模式下,程序可以在适当的时候查询是否有数据可供读取。一般是通过定期的轮询来实现的。

多路复用I/O是一种新的I/O编程模型。传统的套接字服务器的处理方式是对于每一个客户端套接字连接,都新创建一个线程来进行处理。创建线程是很耗时的操作,而有的实现会采用线程池。不过一个请求一个线程的处理模型并不是很理想。原因在于耗费时间创建的线程,在大部分时间可能处于等待的状态。而多路复用I/O的基本做法是由一个线程来管理多个套接字连接。该线程会负责根据连接的状态,来进行相应的处理。多路复用I/O依靠操作系统提供的select或相似系统调用的支持,选择那些已经就绪的套接字连接来处理。可以把多个非阻塞I/O通道注册在某个Selector上,并声明所感兴趣的操作类型。每次调用Selector的select方法,就可以选择到某些感兴趣的操作已经就绪的通道的集合,从而可以进行相应的处理。如果要执行的处理比较复杂,可以把处理转发给其它的线程来执行。

下面是一个简单的使用多路复用I/O的服务器实现。当有客户端连接上的时候,服务器会返回一个Hello World作为响应。

private static class IOWorker implements Runnable {     public void run() {         try {             Selector selector = Selector.open();             ServerSocketChannel channel = ServerSocketChannel.open();             channel.configureBlocking(false);             ServerSocket socket = channel.socket();             socket.bind(new InetSocketAddress("localhost", 10800));             channel.register(selector, channel.validOps());             while (true) {                 selector.select();                 Iterator iterator = selector.selectedKeys().iterator();
                while (iterator.hasNext()) {
                    SelectionKey key = iterator.next();
                    iterator.remove();
                    if (!key.isValid()) {
                        continue;
                    }
                    if (key.isAcceptable()) {
                        ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                        SocketChannel sc = ssc.accept();
                        sc.configureBlocking(false);
                        sc.register(selector, sc.validOps()); 
                    }
                    if (key.isWritable()) {
                        SocketChannel client = (SocketChannel) key.channel();
                        Charset charset = Charset.forName("UTF-8");
                        CharsetEncoder encoder = charset.newEncoder();
                        CharBuffer charBuffer = CharBuffer.allocate(32);
                        charBuffer.put("Hello World");
                        charBuffer.flip();
                        ByteBuffer content = encoder.encode(charBuffer);
                        client.write(content);
                        key.cancel();
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上面的代码给出的只是非常简单的示例程序,只是展示了多路复用I/O的基本使用方式。在开发复杂网络应用程序的时候,使用一些Java NIO网络应用框架会让你事半功倍。目前来说最流行的两个框架是Apache MINANetty。在使用了Netty之后,Twitter的搜索功能速度提升达到了3倍之多。网络应用开发人员都可以使用这两个开源的优秀框架。

分享到:
评论

相关推荐

    i/o多路复用实现的并发服务器

    用selete实现的i/o多路复用并发服务器,socket,在linxu下实现

    IO多路复用之select全面总结(必看篇)

    1、基本概念 IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合: ...与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创

    I/O多路复用实验代码

    这是我的I/O多路复用实验部分的代码,里边只有一个c文件,复制到linux中,使用gcc命令编译,具体看博客:http://blog.csdn.net/mybelief321/article/details/8993138

    解析libevent不同操作系统下如何选择I/O多路复用机制

     Libevent支持多种I/O多路复用技术的关键在于结构体eventop,它的成员是一系列的函数指针, 定义在event-internal.h文件中: struct eventop { const char *name; void *(*init)(struct ...

    linux 系统源码全面剖析

    多路复用I/O GDB原理之ptrace 容器相关 docker实现原理之 - namespace docker实现原理之 - CGroup介绍 docker实现原理之 - CGroup实现原理 docker实现原理之 - OverlayFS实现原理 2.6+内核分析 Epol

    echo 多路I/O的 服务器端

    关于echo 的多路IO 的服务器端的编程

    IO多路复用之poll实例

    本示例演示了使用poll函数处理多路IO复用。本示例在ubuntu + Qt下编译通过的,仅提供学习使用。

    Linux I/O多路复用详解及实例

    主要介绍了Linux I/O多路复用详解及实例的相关资料,并附实例代码,需要的朋友可以参考下

    总结网络IO模型与select模型的Python实例讲解

    网络I/O模型 人多了,就会有问题。web刚出现的时候,光顾的人很少。近年来网络应用规模逐渐扩大,应用的架构也需要随之改变。... 多路复用I/O(multiplexing I/O) 信号驱动式I/O(signal-driven I/O)

    ST推出多路复用NOR闪存移动应用解决方案

    ST发布新的地址-数据多路复用输入/输出(AD MUX I/O)系列产品,这是一个专门为注重成本效益和价值的移动平台设计的全系列NOR闪存解决方案。  AD MUX I/O架构提出了数据地址共用引脚的概念,从而减少了存储芯片的...

    I:O多路复用(多路转接)1

    I:O多路复用(多路转接)1

    传感技术中的利用具有I/O模拟多路复用器的PSoC简化传感器控制设计

    赛普拉斯公司的CY8C21×34可编程系统级芯片(PSoC)混合信号阵列具有一个I/O模拟多路复用器,由于每个引脚都可以被用作一个模拟输入,因此采用单个SoC便能够轻松实现需要大量不同类型传感器的控制应用。本文介绍了在...

    IO多路复用1

    1. I/O多路复用(I/O多路转接) 1. 首先要构造一个关于文件描述符的列表,将要监听的文件描述符添加到该列表中 2. 调用一个系统函数,监听该列表中的文件

    网络编程高级应用 I/O阻塞与非阻塞操作应用

    I/O阻塞与非阻塞操作应用 socket多路复用技术socket信号驱动UDP广播与组播通信

    linux下socket编程之以select方式实现并发服务器

    在linux下的socket编程服务器模型之多路复用I/O,源码经过本人编译,测试,绝对能正确运行。

    飞兆推业界首款多路复用器 扩展SD/SDIO/MMC能力

    飞兆半导体公司 (Fairchild Semiconductor) 的 FSSD06 是首款多路复用器,同时支持高压和双压安全数字 (SD)/安全数字 I/O (SDIO)/多媒体卡 (MMC),并具有扩展 ASIC 和基带处理器 SDIO 端口的能力。FSSD06 非常适用于...

    电源技术中的ST 推出AD MUX I/O系列产品

    意法半导体(ST)宣布一个新的地址-数据多路复用输入/输出(AD MUX I/O)系列产品,这是一个专门为注重成本效益和价值的移动平台设计的全系列NOR闪存解决方案。 AD MUX I/O架构提出了数据地址共用引脚的概念,从而减少...

    IO复用服务器linux C语言开发的包含客户端

    1,服务器编程最好根据实际应用中起用多个进程与多个线程进行操作。 但线程不可过多,CPU频繁切换时会更消耗时间。而且线程经常销毁与创建也是特别消耗资源的。 2,应该引用进守护进程。 (可供初学者读用)

    使用Python的Tornado框架实现一个简单的WebQQ机器人

    WebQQ协议是一套基于HTTP的QQ协议, 而用Python的urllib2库进行请求太慢, 因为HTTP本身就使用socket请求, 所以改用多路复用I/O模型, 而Tornado简单高效, 看过代码后可以轻松上手.平台兼容性很好, 所以选择Tornado作为...

    基于java NIO的简单聊天软件示例

    它是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。 NIO是一种基于通道和缓冲区的I/O方式,它可以使用Native函数库...

Global site tag (gtag.js) - Google Analytics