NIO模式主要优势是体现在对多连接的管理,对众多连接各种事件的转发让处理变得更加高效,所以一般是服务器端才会使用NIO模式,而对于客户端为了方便及习惯使用阻塞模式的Socket进行通信。所以NIO模式的例子也仅仅看下服务端的实现即可。

public class NioServer {

private ByteBuffer readBuffer;

private Selector selector;

private void init() {

readBuffer = ByteBuffer.allocate(1024);

ServerSocketChannel servSocketChannel;

try {

servSocketChannel = ServerSocketChannel.open();

servSocketChannel.configureBlocking(false);

servSocketChannel.socket().bind(new InetSocketAddress(8888));

selector = Selector.open();

servSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

} catch (IOException e) {

e.printStackTrace();

}

}

private void listen() {

while (true) {

try {

selector.select();

Iterator ite = selector.selectedKeys().iterator();

while (ite.hasNext()) {

SelectionKey key = (SelectionKey) ite.next();

ite.remove();

handleKey(key);

}

} catch (Throwable t) {

t.printStackTrace();

}

}

}

private void handleKey(SelectionKey key) throws IOException,ClosedChannelException {

SocketChannel channel = null;

try {

if (key.isAcceptable()) {

ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();

channel = serverChannel.accept();

channel.configureBlocking(false);

channel.register(selector, SelectionKey.OP_READ);

} else if (key.isReadable()) {

channel = (SocketChannel) key.channel();

readBuffer.clear();

int count = channel.read(readBuffer);

if (count > 0) {

readBuffer.flip();

ByteBuffer response = ByteBuffer.wrap(new byte[] { 'r','e', 's', 'p', 'o', 'n', 's', 'e' });

byte[] request=new byte[7];

System.out.println(readBuffer.get(request));

while (response.hasRemaining()) {

channel.write(response);

}

} else {

channel.close();

}

}

} catch (Throwable t) {

t.printStackTrace();

if (channel != null) {

channel.close();

}

}

}

public static void main(String[] args) {

NioServer nioServer = new NioServer();

nioServer.init();

nioServer.listen();

}

}

初始化方法主要做的事情包括分配读缓冲、开启一个ServerSocketChannel通道并设置为非阻塞、绑定8888端口、开启一个选择器Selector、将ServerSocketChannel对象以OP_ACCEPT作为感兴趣事件注册到选择器中。

监听方法主要做的事情是不断通过选择器select出感兴趣的事件,再将对应的key送到handleKey方法处理,分三种事件说明,①OP_ACCEPT事件,一个客户端连接连进来最开始会触发一个接收事件,此时要通过调用ServerSocketChannel对象的accept将客户端连接接收,并将接收到的客户端channel设置为非阻塞,最后将客户端channel以OP_READ事件注册到选择器中;②OP_READ事件,假如客户端连接写入“request”字符串,服务端选择器选择出该通道有字符串待读,从key中获取对应channel并执行read操作,这里会输出“request”字符串,然后向客户端输出“response”字符串;③OP_WRITE事件,这里为方便并没有注册写事件而是直接将字节串写回客户端,实际处理中可以这样:先尝试直接往通道写入,在网络阻塞时即循环写入数据写不了时则注册OP_WRITE事件避免线程阻塞,交给后面选择器select后再次进行写处理。

非阻塞模式提供了另外一种IO处理模型,把阻塞操作改成非阻塞操作,增加了程序编写的难度,但如果要写出高性能高并发的服务端服务则必须掌握NIO模式。

对java感兴趣的朋友可以交流下:

NIO模式例子的更多相关文章

  1. 如何让你的传输更安全——NIO模式和BIO模式实现SSL协议通信

    对于SSL/TLS协议,如果要每个开发者都自己去实现显然会带来不必要的麻烦,正是为了解决这个问题Java为广大开发者提供了Java安全套接字扩展--JSSE,它包含了实现Internet安全通信的一系 ...

  2. Eclipse中开发环境也想把Tomcat 的默认BIO模式改为NIO模式

    1.1 问题 有时候,开发环境我们也想把Tomcat 的默认BIO模式改为NIO模式,该如何改呢? 1.2 方案 通过eclipse里面的server.xml进行修改. 1.3 步骤 首先我们来一起看 ...

  3. 从连接器组件看Tomcat的线程模型——NIO模式

    Tomcat8之后,针对Http协议默认使用org.apache.coyote.http11.Http11NioProtocol,也就是NIO模式.通过之前的博客分析,我们知道Connector组件在 ...

  4. 2、nio的例子实践

    下面的例子,说明了,nio中的三大核心类的基本使用.buffer,channel,selector package com.shengsiyuan.nio; import org.junit.Test ...

  5. AngularJS的简单订阅发布模式例子

    控制器之间的交互方式广播 broadcast, 发射 emit 事件 类似于 js中的事件 , 可以自己定义事件 向上传递直到 document 在AngularJs中 向上传递直到 rootScop ...

  6. 通过生产者消费者模式例子讲解Java基类方法wait、notify、notifyAll

    wait(),notify()和notifyAll()都是Java基类java.lang.Object的方法. 通俗解释wait():在当前线程等待其它线程唤醒.notify(): 唤醒一个线程正在等 ...

  7. JavaScript设计模式--简单工厂模式例子---XHR工厂

    第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方法不要写出Interface.prototype ,因为这是写到接 ...

  8. C++代码学习之一:组合模式例子

    #include"AbstractFile.h" void AbstractFile::add(AbstractFile*) { } void AbstractFile::remo ...

  9. laravel装饰者模式例子

    interface Decorator{ public function display(); } class XiaoFang implements Decorator { private $nam ...

随机推荐

  1. Cocos2D-ObjC:在RPG游戏中混合Swift代码

    我之前写过一个RPG游戏<<熊猫之魂 SoulOfPanda>> 编译器使用的是SpriteBuilder,很好很强大!全部代码都由Objc完成,现在想尝试一下在其中混入Swi ...

  2. uboot-tiny4412启动流程(下)----如何将自己的裸板测试程序加入uboot中启动测试

    今天在工作上搞了一天高通的芯片uboot程序,目的是希望将一个裸板的程序移植到uboot中,并且开机让它运行.这个芯片是NXP4330,目前是高通的一个芯片,基于ARM-contexA9架构,那么就跟 ...

  3. Swift中使用NSLog的问题

    在Swift中如果想要以如下方式执行NSLog,则编译器必定抱怨: class Foo {} NSLog("%@",Foo()) 因为Foo是原生Swift类不是继承自NSObje ...

  4. frameset 与frame 设置的技巧

    今天来写点不一样的.如下图: 实现的效果就是原生的类似于导航形式的frameset. frameset 注意: 包含frameset的网页应该只是作为框架而存在,所以不能有body标签. 这个标签可以 ...

  5. Python中使用rrdtool结合Django进行带宽监控

    我们有个网关需要做下带宽监控,能获取这个数据的唯一方法就是登录到管理界面查看.然后咱就写了个模拟登录的爬虫,定时抓取数据用rrdtool存储,最后通过Django来展示.这里就涉及了python的rr ...

  6. 1QPushButton的使用,QLineEdit的使用,设置组件位置,布局(QHBoxLayout,QGridLayout)

     1.新建一个空Qt项目 2 新建一个新的文件(右击项目à添加新文件) 3 配置pro文件属性 SOURCES += \ main.cpp QT += widgets gui 4 编写main.c ...

  7. Unity插件 - MeshEditor(七)变形动画骨骼及蒙皮

    MeshAnimation在物体的顶点比较多的情况下,悲剧是显而可见的,我一个一个的点选顶点肯定得累死,而且对于形态的调控不是很方便,应该说是很麻烦,要知道,骨骼动画因为有了骨骼以及蒙皮信息而有了灵魂 ...

  8. Java并发框架——公平性

    所谓公平性指所有线程对临界资源申请访问权限的成功率都一样,不会让某些线程拥有优先权.通过前面的CLH Node FIFO学习知道了等待队列是一个先进先出的队列,那么是否就可以说每条线程获取锁时就是公平 ...

  9. iOS中 自定义cell分割线/分割线偏移 韩俊强的博客

    在项目开发中我们会常常遇到tableView 的cell分割线显示不全,左边会空出一截像素,更有甚者想改变系统的分割线,并且只要上下分割线的一个等等需求,今天重点解决以上需求,仅供参考: 每日更新关注 ...

  10. NoSQL数据库之Redis数据库:Redis的介绍与安装部署

     NoSQL(NoSQL = Not Only SQL),它指的是非关系型的数据库.随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的w ...