java中NIO的selector
Posted 健康平安的活着
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中NIO的selector相关的知识,希望对你有一定的参考价值。
一 selector
Selector(选择器)是Java NIO中能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件,一个Selector可以同时轮询多个Channel,只需要一个线程负责Selector的轮询,就可以接入成千上万的客户端。
二 selector的操作
1.selector的创建
Selector的创建
通过调用Selector.open()方法创建一个Selector,如下:
Selector selector = Selector.open();
2.向selector注册管道
为了将Channel和Selector配合使用,必须将channel注册到selector上。通过SelectableChannel.register()方法来实现,如下:
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, Selectionkey.OP_READ);
3.
SelectionKey
当向Selector注册Channel时,register()方法会返回一个SelectionKey对象。
4.interest集合
就像向Selector注册通道一节中所描述的,interest集合是你所选择的感兴趣的事件集合。
5.
ready集合
ready 集合是通道已经准备就绪的操作的集合。
6.selectedKeys()
当像Selector注册Channel时,Channel.register()方法会返回一个SelectionKey 对象
三 selector的案例操作
3.1 客户端
package com.cf.demo.nio.selector;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class SelectorClient {
private Selector selector;
private SocketChannel channel = null;
private ByteBuffer outBuff = ByteBuffer.allocate(1024);
private ByteBuffer inBuff = ByteBuffer.allocate(1024);
private int keys = 0;
public static void main(String[] args) throws IOException {
new SelectorClient().start();
}
public void start() throws IOException {
initClient();
listen();
}
public void initClient() throws IOException {
channel = SocketChannel.open();
selector = Selector.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress("127.0.0.1", 8888));
channel.register(selector, SelectionKey.OP_CONNECT);
}
public void listen () throws IOException {
while(true) {
//
keys = this.selector.select();
if (keys > 0) {
Iterator it = this.selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
it.remove();
if (key.isConnectable()) {
SocketChannel channel = (SocketChannel) key.channel();
if (channel.isConnectionPending()) {
channel.finishConnect();
System.out.println("Complete connect.");
}
channel.register(selector, SelectionKey.OP_WRITE);
} else if (key.isWritable()) {
SocketChannel channel = (SocketChannel) key.channel();
outBuff.clear();
System.out.println("client is write data start.");
channel.write(outBuff.wrap("I'm client.".getBytes()));
channel.register(selector, SelectionKey.OP_READ);
System.out.println("client is write data end.");
} else if (key.isReadable()) {
// read
SocketChannel channel = (SocketChannel) key.channel();
inBuff.clear();
int length = channel.read(inBuff);
String msg = "server receive msg:" + new String(inBuff.array(), 0, length);
System.out.println(msg);
}
}
}
}
}
}
3.2 服务端:
package com.cf.demo.nio.selector;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class SelectorServer {
private Selector selector;
private ServerSocketChannel serverChannel = null;
private int keys = 0;
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
new SelectorServer().start();
}
public void start() throws IOException {
initServer();
listen();
}
public void initServer() throws IOException {
// 获取一个sokcet通道,
serverChannel = ServerSocketChannel.open();
// 获取一个通道管理器
selector = Selector.open();
// 非阻塞
serverChannel.configureBlocking(false);
// 连接服务器
serverChannel.socket().bind(new InetSocketAddress("127.0.0.1", 8888));
// 吧serverChannel这个通道注册到管理器对象selector中去,当有客户端连接时触发
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
}
public void listen() throws IOException {
System.out.println("server start.");
while(true) {
//
keys = this.selector.select();
if (keys > 0) {
Iterator it = this.selector.selectedKeys().iterator();
while (it.hasNext()) {
SelectionKey key = (SelectionKey) it.next();
it.remove();
// 是否完成套接字连接
if (key.isAcceptable()) {
serverChannel = (ServerSocketChannel) key.channel();
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);
channel.write(ByteBuffer.wrap(new String("Hello Client.").getBytes()));
channel.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
// read
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(1024);
int length = channel.read(buffer);
String msg = "server receive msg:" + new String(buffer.array(), 0, length);
System.out.println(msg);
}
}
} else {
}
}
}
}
以上是关于java中NIO的selector的主要内容,如果未能解决你的问题,请参考以下文章
Java NIO 的前生今世 之四 NIO Selector 详解