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 ...
随机推荐
- CentOS7.2安装Weblogic12c出现的问题
Weblogic12c安装到步骤:Prerequisite Checks 时,会进行操作系统版本的校验,即checking operating system certification. 此处 ...
- Python 3 智能发音
真是十分神奇.. import win32com.client import time s = win32com.client.Dispatch("SAPI.SpVoice") s ...
- 关于bootstrap在IE8下不能支持自适应的问题
说到这个问题,我就想吐槽下IE了,开发这么多版本,每个版本都有一些这样那样的问题不支持,别的正常的浏览器咋都能支持呢?真是垃圾浏览器!!!! 说归说,但是IE现在用的人多啊,怎么办?这个问题还是得解决 ...
- ubuntu安装qq
安装的版本是国际版 1.安装依赖库 sudo apt-get install libgtk2.0-0:i386 sudo apt-get install lib32ncurses5 2.下载 下载链接 ...
- jvm java虚拟机 新生代的配置
1.1.1.1. -Xmn参数 参数-Xmn1m可以用于设置新生代的大小.设置一个较大的新生代会影响老生代的大小,因为这两者的总和是一定的,这个系统参数对于系统性能以及GC行为有很大的影响,新生代一般 ...
- Retrofit 2.0 超能实践(一),okHttp完美支持Https传输
http: //blog.csdn.net/sk719887916/article/details/51597816 Tamic首发 前阵子看到圈子里Retrofit 2.0,RxJava(Andro ...
- 使用 symbolicatecrash 解析崩溃堆栈
一.先引用一位牛人的博贴: xcode解crashlog工具symbolicatecrash的使用 在xocde编译app的时候会同时生成一个以dsym(该app对应的符号表)作为后缀的文件,每个ap ...
- linux中echo的用法
1.echo命令我们常用的选项有两个,一个是-n,表示输出之后不换行,另外一个是-e,表示对于转义字符按相应的方式处理,如果不加-e那么对于转义字符会按普通字符处理. 2.echo输出时的转义字符 \ ...
- [GitHub]第五讲:团队合作流程
文章转载自:http://blog.csdn.net/loadsong/article/details/51591631 前几天还都是一个开发者唱独角戏.但是尽管如此也可以看出 Git 带来的便利了, ...
- 如何在Cocos2D游戏中实现A*寻路算法(二)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流 ...