服务器
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
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;
public class SelectorServiceDemo {
public static void main(String[] args) throws Exception {
int port = 8000;
// 通过open()方法找到Selector
Selector selector = Selector.open();
// 打开服务器的通道
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
// 服务器配置为非阻塞
serverSocketChannel.configureBlocking(false);
ServerSocket serverSocket = serverSocketChannel.socket();
InetSocketAddress address = new InetSocketAddress(port);
// 进行服务的绑定
serverSocket.bind(address);
// 注册到selector,等待连接
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("服务器运行,端口:" + port);
// 数据缓冲区
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (true) {
if ((selector.select()) > 0) {
// 选择一组键,并且相应的通道已经准备就绪
// 取出全部生成的key
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> iter = selectedKeys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
if (key.isAcceptable()) {
acceptable(key, byteBuffer, selector);
} else if (key.isReadable() && key.isValid()) {
readable(selector, byteBuffer, key);
} else if (key.isWritable() && key.isValid()) {
writable(selector, byteBuffer, key);
}
}
// 清除全部的key
selectedKeys.clear();
}
}
}
public static void writable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
byteBuffer.clear();
// 向缓冲区中设置内容
byteBuffer.put(("欢迎学习NIO教程").getBytes());
byteBuffer.flip();
// 输出内容
client.write(byteBuffer);
client.register(selector, SelectionKey.OP_READ);
}
public static void readable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
byteBuffer.clear();
// 读取内容到缓冲区中
int readSize = client.read(byteBuffer);
if (readSize > 0) {
System.out.println("服务器端接受客户端数据:" + new String(byteBuffer.array(), 0, readSize));
client.register(selector, SelectionKey.OP_WRITE);
}
}
public static void acceptable(SelectionKey key, ByteBuffer byteBuffer, Selector selector) throws IOException {
ServerSocketChannel server = (ServerSocketChannel) key.channel();
// 接收新连接 和BIO写法类是都是accept
SocketChannel client = server.accept();
// 配置为非阻塞
client.configureBlocking(false);
byteBuffer.clear();
// 向缓冲区中设置内容
byteBuffer.put(("当前的时间为:" + new Date()).getBytes());
byteBuffer.flip();
// 输出内容
client.write(byteBuffer);
client.register(selector, SelectionKey.OP_READ);
}
}
结果
![图一.png](https://upload-images.jianshu.io/upload_images/25693962-5ca5a931b4852ff5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
客户端
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
public class SelectorClientDemo {
public static void main(String[] args) throws Exception {
// 打开socket通道
SocketChannel socketChannel = SocketChannel.open();
// 设置为非阻塞方式
socketChannel.configureBlocking(false);
// 通过open()方法找到
Selector selector = Selector.open();
// 注册连接服务端socket动作
socketChannel.register(selector, SelectionKey.OP_CONNECT);
// 连接
socketChannel.connect(new InetSocketAddress("127.0.0.1", 8000));
/* 数据缓冲区 */
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
while (true) {
if ((selector.select()) > 0) {
// 选择一组键,并且相应的通道已经准备就绪
Set<SelectionKey> selectedKeys = selector.selectedKeys();// 取出全部生成的key
Iterator<SelectionKey> iter = selectedKeys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next(); // 取出每一个key
if (key.isConnectable()) {
connection(selector, byteBuffer, key);
} else if (key.isReadable() && key.isValid()) {
readable(selector, byteBuffer, key);
} else if (key.isWritable() && key.isValid()) {
writable(selector, byteBuffer, key);
}
}
selectedKeys.clear(); // 清楚全部的key
}
}
}
public static void writable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
byteBuffer.clear();
// 向缓冲区中设置内容
byteBuffer.put(("学习NIO!").getBytes());
byteBuffer.flip();
// 输出内容
client.write(byteBuffer);
client.register(selector, SelectionKey.OP_READ);
}
public static void readable(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
byteBuffer.clear();
// 读取内容到缓冲区中
int readSize = client.read(byteBuffer);
if (readSize > 0) {
System.out.println("客户端接受服务器端数据:" + new String(byteBuffer.array(), 0, readSize));
client.register(selector, SelectionKey.OP_WRITE);
}
}
public static void connection(Selector selector, ByteBuffer byteBuffer, SelectionKey key)
throws IOException, ClosedChannelException {
SocketChannel client = (SocketChannel) key.channel();
if (client.isConnectionPending()) {
client.finishConnect();
byteBuffer.clear();
// 向缓冲区中设置内容
byteBuffer.put(("isConnect,当前的时间为:" + new Date()).getBytes());
byteBuffer.flip();
// 输出内容
client.write(byteBuffer);
}
client.register(selector, SelectionKey.OP_READ);
}
}
结果