服务器端
package com.xmg.nio.selector;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
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.nio.charset.Charset;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class TestServer {
private static Map<String, SocketChannel> clientMap = new HashMap();
private static int CLIENT_ID = 0;
public static void main(String[] args) throws Exception {
ServerSocketChannel serverChannel;
serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);
ServerSocket serverSocket = serverChannel.socket();
serverSocket.bind(new InetSocketAddress(8899));
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
while (true) {
try {
selector.select(); // 阻塞
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> itera = selectedKeys.iterator();
while (itera.hasNext()) {
SelectionKey key = itera.next();
final SocketChannel client;
try {
if (key.isAcceptable()) {
ServerSocketChannel channel = (ServerSocketChannel) key.channel();
client = channel.accept();
// 设置非阻塞模式
client.configureBlocking(false);
// 注册关心事件
client.register(selector, SelectionKey.OP_READ);
String clientId = "客户端【" + CLIENT_ID++ + "】";
clientMap.put(clientId, client);
} else if (key.isReadable()) {
client = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(512);
int count = client.read(buffer);
if (count > 0) {
buffer.flip();
Charset charset = Charset.forName("utf-8");
String message = String.copyValueOf(charset.decode(buffer).array());
System.out.println(client + ":" + message);
String senderKey = null;
for (Map.Entry<String, SocketChannel> entry : clientMap.entrySet()) {
if (client == entry.getValue()) {
senderKey = entry.getKey();
break;
}
}
for (Map.Entry<String, SocketChannel> entry : clientMap.entrySet()) {
SocketChannel value = entry.getValue();
ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
writeBuffer.put((senderKey + ":" + message).getBytes());
writeBuffer.flip();
value.write(writeBuffer);
}
}
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
selectedKeys.clear();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
客户端
package com.xmg.nio.selector;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.time.LocalDateTime;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestClient {
public static void main(String[] args) {
SocketChannel channel;
try {
channel = SocketChannel.open();
channel.configureBlocking(false);
Selector selector = Selector.open();
channel.register(selector, SelectionKey.OP_CONNECT);
channel.connect(new InetSocketAddress("localhost", 8899));
while (true) {
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
for (SelectionKey key : selectedKeys) {
if (key.isConnectable()) {
SocketChannel client = (SocketChannel) key.channel();
// 连接事件在进程中
if (client.isConnectionPending()) {
client.finishConnect();
ByteBuffer buffer = ByteBuffer.allocate(1024);
buffer.put((LocalDateTime.now() + "连接成功").getBytes());
buffer.flip();
channel.write(buffer);
// 新建线程来监听输入
ExecutorService executorService = Executors
.newSingleThreadExecutor(Executors.defaultThreadFactory());
executorService.submit(() -> {
while (true) {
try {
buffer.clear();
InputStreamReader input = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(input);
String sendMessage = br.readLine();
buffer.put(sendMessage.getBytes());
buffer.flip();
client.write(buffer);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
client.register(selector, SelectionKey.OP_READ);
} else if (key.isReadable()) {
SocketChannel client = (SocketChannel) key.channel();
ByteBuffer readBuffer = ByteBuffer.allocate(1024);
int read = client.read(readBuffer);
if (read > 0) {
String message = new String(readBuffer.array(), 0, read);
System.out.println(message);
}
}
}
selectedKeys.clear();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行完成截图
server
客户端