NIO模式例子
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模式例子的更多相关文章
- 如何让你的传输更安全——NIO模式和BIO模式实现SSL协议通信
对于SSL/TLS协议,如果要每个开发者都自己去实现显然会带来不必要的麻烦,正是为了解决这个问题Java为广大开发者提供了Java安全套接字扩展--JSSE,它包含了实现Internet安全通信的一系 ...
- Eclipse中开发环境也想把Tomcat 的默认BIO模式改为NIO模式
1.1 问题 有时候,开发环境我们也想把Tomcat 的默认BIO模式改为NIO模式,该如何改呢? 1.2 方案 通过eclipse里面的server.xml进行修改. 1.3 步骤 首先我们来一起看 ...
- 从连接器组件看Tomcat的线程模型——NIO模式
Tomcat8之后,针对Http协议默认使用org.apache.coyote.http11.Http11NioProtocol,也就是NIO模式.通过之前的博客分析,我们知道Connector组件在 ...
- 2、nio的例子实践
下面的例子,说明了,nio中的三大核心类的基本使用.buffer,channel,selector package com.shengsiyuan.nio; import org.junit.Test ...
- AngularJS的简单订阅发布模式例子
控制器之间的交互方式广播 broadcast, 发射 emit 事件 类似于 js中的事件 , 可以自己定义事件 向上传递直到 document 在AngularJs中 向上传递直到 rootScop ...
- 通过生产者消费者模式例子讲解Java基类方法wait、notify、notifyAll
wait(),notify()和notifyAll()都是Java基类java.lang.Object的方法. 通俗解释wait():在当前线程等待其它线程唤醒.notify(): 唤醒一个线程正在等 ...
- JavaScript设计模式--简单工厂模式例子---XHR工厂
第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方法不要写出Interface.prototype ,因为这是写到接 ...
- C++代码学习之一:组合模式例子
#include"AbstractFile.h" void AbstractFile::add(AbstractFile*) { } void AbstractFile::remo ...
- laravel装饰者模式例子
interface Decorator{ public function display(); } class XiaoFang implements Decorator { private $nam ...
随机推荐
- 2016年年终CSDN博客总结
2015年12月1日,结束了4个月的尚观嵌入式培训生涯,经过了几轮重重面试,最终来到了伟易达集团.经过了长达3个月的试用期,正式成为了伟易达集团的助理工程师. 回顾一年来的学习,工作,生活.各种酸甜苦 ...
- Openresty 数据共享API.Data Sharing within an Nginx Worker
摘要自:https://github.com/openresty/lua-nginx-module/#data-sharing-within-an-nginx-worker 每nginx worker ...
- JAVA面向对象-----访问修饰符
访问修饰符是用来控制类.属性.方法的可见性的关键字称之为访问修饰符. 1.public 一个类中,同一包中,子类中,不同包中 2.protected 一个类中,同一包中,子类中 3.default 一 ...
- OpenCV+OpenGL 双目立体视觉三维重建
0.绪论 这篇文章主要为了研究双目立体视觉的最终目标--三维重建,系统的介绍了三维重建的整体步骤.双目立体视觉的整体流程包括:图像获取,摄像机标定,特征提取(稠密匹配中这一步可以省略),立体匹配,三维 ...
- RxJava(二) map操作符用法详解
欢迎转载,转载请标明出处: http://blog.csdn.net/johnny901114/article/details/51531348 本文出自:[余志强的博客] 1 map操作符的作用 R ...
- Android Multimedia框架总结(八)Stagefright框架之AwesomePlayer及数据解析器
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52503057 前言:前面一篇分析了medi ...
- FFmpeg源代码简单分析:avcodec_open2()
===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...
- Android项目开发填坑记-so文件引发的攻坚战
故事的最初 我负责的项目A要求有播放在线视频的功能,当时从别人的聊天记录的一瞥中发现百度有相关的SDK,当时找到的是Baidu-T5Player-SDK-Android-1.4s,项目中Demo的so ...
- Java基础---Java---基础加强---类加载器、委托机制、AOP、 动态代理技术、让动态生成的类成为目标类的代理、实现Spring可配置的AOP框架
类加载器 Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader,AppClassLoader 类加载器也是Jav ...
- 详解EBS接口开发之更新供应商付款方法
更新供应商地点层的付款方法API DECLARE --API 参数 l_external_payee_rec_type iby_disbursement_setup_pub.external_paye ...