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.Date;
import java.util.Iterator;
import java.util.Set;
/**
* Created by mapan on 2014/8/18.
*/
public class NioServer {
Selector selector = null;
public NioServer(int port) throws IOException {
selector = Selector.open();
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(port));
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
}
public void handle() throws IOException {
while (!Thread.interrupted()) {
selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = selectionKeys.iterator();
while (iterator.hasNext()) {
SelectionKey next = iterator.next();
iterator.remove();
if (next.isAcceptable()) {
ServerSocketChannel channel = (ServerSocketChannel) next.channel();
SocketChannel accept = channel.accept();
accept.configureBlocking(false);
accept.register(selector, SelectionKey.OP_READ);
}else if (next.isReadable()) {
SocketChannel channel = (SocketChannel) next.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int read = channel.read(byteBuffer);
String readString = new String(byteBuffer.array(), 0, read).trim();
System.out.println(readString);
if (readString.equals("quit")) {
channel.close();
} else {
// 这里也可以不用 下面一句话注册写事件,直接通过 channel.write() 去给客户端返回数据
channel.register(selector, SelectionKey.OP_WRITE);
}
}else if (next.isWritable()) {
String date = (new Date()).toString() + "\r\n";
SocketChannel channel = (SocketChannel) next.channel();
channel.write(ByteBuffer.wrap(date.getBytes()));
next.interestOps(SelectionKey.OP_READ);
}
}
}
}
public static void main(String[] args) throws IOException {
NioServer nioServer = new NioServer(9999);
nioServer.handle();
}
}
说明:
再nio socket中,打开的是双向通道,如果 建立连接以后,是直接可以写的:写的代码如下:
channel.write()
但是这个在nio socket里面是不推荐的,建议还是通过注册相应的写事件,向客户端返回数据。
这个只是简单的一个 nio socket的事例代码。