在Java中使用NIO进行网络编程
2009-12-29 00:00:00 来源:WEB开发网我们通过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
}
}
在这里,我们又进一步对Selector注册了相关的事件:key.interestOps(SelectionKey.OP_READ);
这样,我们就实现了基于NIO的Echo 系统。
更多精彩
赞助商链接