网络编程NIO-异步
异步I/O是没有阻塞地读写数据的方法。通常在代码进行read调用时,代码会阻塞直至可供读取的数据。同样,write调用将会阻塞直至数据能够写入。
1、selector是一个对象,可以注册到很多个channel上,监听各个channel上发生的事件,并且能够根据事件情况决定channel读写,这样通过一个线程管理多个channel
创建selector:
Selector selector = Selector.open();
注册channel到selector:
channel.configureBlocking(false);
SelectionKey key = chanenl.register(selector, SelecltionKey.OP_READ_;
注意,注册channel必须设置为异步模式才可以。register调用的返回值是selectionKey。这个对象待办这个通道在此selector上的这个注册。当某个selector
通知你某个传入事件时,它是通过提高对应于该事件的SelectionKey来进行的。selectionKey还可以用于取消通过的注册
2、channel和selector
Channel channel = selectionKey.channel();
Selector selector = selectioKey.selector();
demo:
public class MultiPortEcho {
private int ports[];
private ByteBuffer echoBuffer = ByteBuffer.allocate(1024);
public MultiPortEcho(int ports[]) throws IOException {
this.ports = ports;
go();
}
private void go() throws IOException {
//create selector
Selector selector = Selector.open();
//为每个端口打开一个监听,并把这些监听注册到selector中
for(int i = 0; i < ports.length; ++i) {
//打开一个serverSocketChannel
ServerSocketChannel ssc = ServerSocketChnanel.open();
ssc.configureBlocking(false);//设置为非阻塞
ServerSocket ss = ssc.socket();
InetSocketAddress address = new InetSocketAddress(ports[i]);
ss.bind(address); //监听一个端口
//注册到selector
SelectionKey key = ssc.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("going to listen to " + ports[i]);
}
while(true) {
int num = selector.select();//返回所发生的事件的数量
Set selectedKeys = selector.selectKeys();
Iterator it = selectedKeys.iterator();
while(it.hasNext()) {
SelectionKey key = (SelectionKey)it.next();
//监听新连接,调用readops方法,检查发生了什么类型的事件
if((key.readyOps() & selectionKey.OP_ACCEPT) == SelectionKey.OP_ACCEPT) {
//接受一个新连接
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = ssc.accept();
sc.configureBlocking(false);
//将新连接注册到selector。
SelectionKey newKey = sc.register(selector, SelectionKey.OP_READ);
it.remove();
System.out.println("got connection from " + sc);
}else if( (key.readyOps() & SelectionKey.OP_READ) == SelectionKey.OP_READ) {
SocketChannel sc = (SocketChannel)key.channel();
int bytesEchoed = 0;
while(true) {
echoBuffer.clear();
int r = sc.read(echoBuffer);
if( r <= 0 ) {
break;
}
echoBuffer.flip();
sc.write(echoBuffer);
bytesEchoed += r;
}
System.out.println("echoed" + bytesEchoed + "from" + sc);
it.remove();
// System.out.println( "going to clear" ); // selectedKeys.clear(); // System.out.println( "cleared" );
}
}
static public void main(String args2[]) throws Exception {
String args[]={"9001","9002","9003"};
if (args.length <= 0) {
System.err.println("Usage: java MultiPortEcho port [port port ...]");
System.exit(1);
}
int ports[] = new int[args.length];
for (int i = 0; i < args.length; ++i) {
ports[i] = Integer.parseInt(args[i]);
}
new MultiPortEcho(ports);
}
}
}
}
最新文章
- Yii 2.x RESTful 应用 - 类图
- 基础3.Jquery操作Dom
- ThreadLocal用法和实现原理
- Nginx使用webbench进行压力测试
- iOS WKWebView详解
- 112. Path Sum
- SQL Server数据库学习笔记-外键
- NOIP2009 最优贸易
- alpha-咸鱼冲刺day6-紫仪
- Paper Read: Convolutional Image Captioning
- git之sourceTree操作流程
- Oracle 学习笔记 (七)
- python3 与 Django 连接数据库报错:ImportError: No module named &#39;MySQLdb&#39;
- gcc和gdb使用笔记
- Coding in Delphi(前4章翻译版本) (PDF)
- http 本地服务器设置任意IP访问对应的文件夹
- 微信小程序初体验与DEMO分享
- Ubuntu环境变量解析
- 软工网络15团队作业8——Beta阶段敏捷冲刺(用户使用调查报告)
- 解决Win7&;Win8 64位下Source Insight提示未完整安装的问题[转]
热门文章
- 【归纳】Layui table.render里的json后台传入
- Codeforces Round #518 (Div. 1) Computer Game 倍增+矩阵快速幂
- 数组之间的比较应当用Arrays.equals()
- 常用jstl
- 【leetcode】905. Sort Array By Parity
- Java反射学习-4 - 反射调用方法
- ECS运维:操作系统有异常?诊断日志来帮忙!
- linux0.11内核源码——boot和setup部分
- flask-路转换器
- Java学习之包