您的位置:首页 > 其它

io-nio-socket步步为营(三)NIO

2017-10-17 18:11 357 查看
原理:

运用reactor模式

Selector是核心-分发器A multiplexor of SelectableChannel objects。

能检测任意个注册过的channel上的事件,并分发事件,内部实现不用考虑,封装的好处。

 

client没必要用NIO,使用http://luckywnj.iteye.com/blog/1744283中的client

server,

需要多线程的么?workthread?如何写?

 

/**
* @author timeriver.wang
* @version 2013-1-7 11:50:33 PM
*/
public class NIOServer {
public static void main(String[] args) throws Exception {
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(8899));
serverSocketChannel.configureBlocking(false);
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

Charset charset = Charset.forName("UTF-8");
CharsetDecoder decoder = charset.newDecoder();
CharsetEncoder encoder = charset.newEncoder();
ByteBuffer clientBuffer = ByteBuffer.allocate(1024);

while (true) {
// 貌似两个client同时连,返回也是1?在select处阻塞,这样避免线程卡死耗尽资源?
//		    int sel = selector.select();
int sel = selector.select(3000);
if (sel == 0) {
continue;
}
Set<SelectionKey> set = selector.selectedKeys();
System.out.println(set.size());
Iterator<SelectionKey> keyIter = set.iterator();
while (keyIter.hasNext()) {
SelectionKey key = keyIter.next();
System.out.println(key);
// channel is ready to accept a new socket connection
if (key.isAcceptable()) {
SocketChannel serverChannel = ((ServerSocketChannel) key.channel()).accept();
//					为serverChannel再设置一次否则,java.nio.channels.IllegalBlockingModeException,
serverChannel.configureBlocking(false);
SelectionKey skey = serverChannel.register(key.selector(),SelectionKey.OP_READ);
System.out.println("acceptable: serverChannel="+serverChannel+",skey="+skey);
}else if (key.isReadable()) {// channel is ready for reading
SocketChannel serverChannel = (SocketChannel) key.channel();
clientBuffer.clear();
long bytesRead = serverChannel.read(clientBuffer);
if (bytesRead == -1) {
serverChannel.close();
} else {
clientBuffer.flip();
String receivedMsg = decoder.decode(clientBuffer).toString();
System.out.println("receive msg: " + receivedMsg);
SelectionKey skey = serverChannel.register(selector,SelectionKey.OP_WRITE);
System.out.println("readable "+skey);
skey.attach(receivedMsg);
}
} else if (key.isWritable()) { //channel is ready for writing
SocketChannel serverChannel = (SocketChannel) key.channel();
String sendMsg = (String) key.attachment();
ByteBuffer block = encoder.encode(CharBuffer.wrap("Hello !"+sendMsg));
serverChannel.write(block);
SelectionKey skey = serverChannel.register(key.selector(),SelectionKey.OP_READ);
System.out.println("write "+skey);
}
keyIter.remove();
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: