selector.selectedKeys ().iterator();
while (keyIter.hasNext()) {
SelectionKey key = keyIter.next();// Keyisbitmask
// Serversocketchannelhaspendingconnectionrequests?
if (key.isAcceptable()) {
protocol.handleAccept(key);
}
// Clientsocketchannelhaspendingdata?
if (key.isReadable()) {
protocol.handleRead(key);
}
// Clientsocketchannelisavailableforwritingand
// keyisvalid(i.e.,channelnotclosed)?
if (key.isValid() && key.isWritable()) {
protocol.handleWrite(key);
}
keyIter.remove();// removefromsetofselectedkeys
}
}
}
}
在Java中使用NIO进行网络编程(3)
时间:2011-04-03 博客园 逖靖寒
我们通过listnChannel.register(selector, SelectionKey.OP_ACCEPT); 注册了一个 我们感兴趣的事件,然后调用selector.select(TIMEOUT)等待订阅的时间发生,然后再采 取相应的处理措施。
最后我们实现EchoSelectorProtocol
package com.cnblogs.gpcuster;
import java.nio.channels.SelectionKey;
import java.nio.channels.SocketChannel;
import java.nio.channels.ServerSocketChannel;
import java.nio.ByteBuffer;
import java.io.IOException;
public class EchoSelectorProtocol implements TCPProtocol {
private int bufSize;// SizeofI/Obuffer
public EchoSelectorProtocol(int bufSize) {
this.bufSize = bufSize;
}
public void handleAccept(SelectionKey key) throws IOException {
SocketChannel clntChan = ((ServerSocketChannel) key.channel ()).accept();
clntChan.configureBlocking(false);// Mustbenonblockingtoregister
// Registertheselectorwithnewchannelforreadandattachbytebuffer
clntChan.register(key.selector(), SelectionKey.OP_READ, ByteBuffer
.allocate(bufSize));
}
public void handleRead(SelectionKey key) throws IOException {
// Clientsocketchannelhaspendingdata
SocketChannel clntChan = (SocketChannel) key.channel();
ByteBuffer buf = (ByteBuffer) key.attachment();
long bytesRead = clntChan.read(buf);
if (bytesRead == -1) {// Didtheotherendclose?
clntChan.close();
} else if (bytesRead > 0) {
// Indicateviakeythatreading/writingarebothofinterestnow.
key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
}
}
public void handleWrite(SelectionKey key) throws IOException {
/*
* Channelisavailableforwriting,andkeyisvalid(i.e.,clientchannel
* notclosed).
*/
// Retrievedatareadearlier
ByteBuffer buf = (ByteBuffer) key.attachment();
buf.flip();// Preparebufferforwriting
SocketChannel clntChan = (SocketChannel) key.channel();
clntChan.write(buf);
if (!buf.hasRemaining()) {// Buffercompletelywritten?
// Nothingleft,sonolongerinterestedinwrites
key.interestOps(SelectionKey.OP_READ);
}
buf.compact();// Makeroomformoredatatobereadin
}
}
|