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. PGM:贝叶斯网的参数估计2

    http://blog.csdn.net/pipisorry/article/details/52599321 没时间看了,下次再看... 具有共享参数的学习模型 全局参数共享 局部参数共享 具有 共 ...

  2. 详解EBS接口开发之应收INVOICE导入

    (一)应收INVOICE常用标准表简介 1.1   常用标准表 如下表中列出了与应收INVOICE导入相关的表和说明: 表名 说明 其他信息 RA_BATCH_SOURCES_ALL AR事务处理来源 ...

  3. android 集成微博常见问题

    我们在做微博集成登录.分享.聊天的时候,肯定会遇到很多的坑,这里总结下常见的问题. 文件不存在 C8998 的解决方法 如图我们走微博授权登录的时候如果OAuth2.0 授权设置回调页面设置和本地的不 ...

  4. 21 viewPager--- hzScrollView ----llContainer

    结构: MainActivity.java package com.qf.day21_hsviewpagerfragment_demo5; import java.util.ArrayList; im ...

  5. Hibernate缓存集成IMDG

    1 第三方缓存插件 除了Ehcache这种轻量级的缓存方案外,几乎所有IMDG产品都提供了对Hibernate二级缓存的直接支持,常用的有: Ø  Hazelcast Ø  GridGain Ø  J ...

  6. Android开发 无法导入ViewPagerIndicator或其他开源框架无法导入

    这个问题又花费了好长时间,其实就是很简单的问题,因为各种开源框架的库名称都叫liberary,如果上次导入其他开源框架没有更改名称的话,你再导入其他第三库的时候,系统发现重名,就提示无法导入现象. 解 ...

  7. Linux网络和进程管理

     1) 计算机网络是通过外围的设备和连接,将分布在相同或不同区域的多台计算机 连接在一起所形成的集合.网络中的计算机实现彼此间互相通信,并且可以共 同使用硬件.软件和数据资源,实现资源共享.Lin ...

  8. 巨星陨落 - Jim Gary

    偶然在微软Research中搜论文时搜到了神牛Jim Gary的paper,看着照片有点眼熟,貌似在买过的哪本书中见过.于是就饶有兴致地看着Jim的生平介绍,结果-  "Dr. Gray j ...

  9. iPhone全部设备分辨率速查

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交 ...

  10. Java并发框架——AQS超时机制

    AQS框架提供的另外一个优秀机制是锁获取超时的支持,当大量线程对某一锁竞争时可能导致某些线程在很长一段时间都获取不了锁,在某些场景下可能希望如果线程在一段时间内不能成功获取锁就取消对该锁的等待以提高性 ...