BIO-会产生阻塞
NIO-非阻塞
单线程模型-轮询模式--相当于selector负责client的连接并负责client的读写
package com.xmg.nio;
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;
import java.util.Set;
public class Server {
public static void main(String[] args) throws IOException {
ServerSocketChannel ssc = ServerSocketChannel.open();
ssc.socket().bind(new InetSocketAddress("127.0.0.1", 8888));
ssc.configureBlocking(false); //设置非阻塞状态,重要
System.out.println("server started, listening on :" + ssc.getLocalAddress());
Selector selector = Selector.open();
ssc.register(selector, SelectionKey.OP_ACCEPT); //注册连接请求监听器
while(true) {
selector.select(); //这个操作是阻塞方法
Set<SelectionKey> keys = selector.selectedKeys(); //很多注册监听器,为set类型
Iterator<SelectionKey> it = keys.iterator();
while(it.hasNext()) {
SelectionKey key = it.next();
it.remove(); //删除掉这个事件,防止下次重复遍历
handle(key);
}
}
}
private static void handle(SelectionKey key) {
if(key.isAcceptable()) { //客户端请求连接
try {
ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
SocketChannel sc = ssc.accept(); //客户端socketchannel建立
sc.configureBlocking(false); //设置客户端为非阻塞
sc.register(key.selector(), SelectionKey.OP_READ ); //注册读监听器
} catch (IOException e) {
e.printStackTrace();
} finally {
}
} else if (key.isReadable()) { //flip
SocketChannel sc = null;
try {
sc = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(512);
buffer.clear();
int len = sc.read(buffer); //读取数据
if(len != -1) {
System.out.println(new String(buffer.array(), 0, len));
}
ByteBuffer bufferToWrite = ByteBuffer.wrap("HelloClient".getBytes());
sc.write(bufferToWrite); //写出数据
} catch (IOException e) {
e.printStackTrace();
} finally {
if(sc != null) {
try {
sc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
}
ServerSocketChannel 可读可写,双向通道
设定阻塞为false,configBlocking(false)
selector.select()方法是阻塞的
ExecutorService pool = Executors.newFixedThreadPool(50);
new CompletionHandler