1.服务端
public class GroupChatServer {
private final ServerSocketChannel serverSocketChannel;
private final Selector selector;
public GroupChatServer() throws IOException {
this.serverSocketChannel = ServerSocketChannel.open();
this.serverSocketChannel.bind(new InetSocketAddress(6666));
this.serverSocketChannel.configureBlocking(false);
this.selector = Selector.open();
this.serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
}
public static void main(String[] args) throws IOException {
GroupChatServer groupChatServer = new GroupChatServer();
groupChatServer.startServer();
}
@SuppressWarnings("InfiniteLoopStatement")
public void startServer() throws IOException {
while (true) {
selector.select();
Set<SelectionKey> selectionKeys = selector.selectedKeys();
for (Iterator<SelectionKey> iterator = selectionKeys.iterator(); iterator.hasNext(); ) {
SelectionKey key = iterator.next();
if (key.isAcceptable()) {
handleAcceptable();
} else if (key.isReadable()) {
SocketChannel self = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(512);
int read = getRead(key, self, buffer);
if(read>0){
forwardMessage(key,buffer);
}
}
iterator.remove();
}
}
}
private void handleAcceptable() throws IOException {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ, ByteBuffer.allocate(512));
System.out.println(socketChannel.getRemoteAddress() + "客户端上线啦");
}
private int getRead(SelectionKey key, SocketChannel self, ByteBuffer buffer) throws IOException {
int read = 0;
try {
read = self.read(buffer);
System.out.println("接收到客户端信息[" + new String(buffer.array()).trim() + "],转发给其他客户端");
} catch (IOException e) {
System.out.println(self.getRemoteAddress() + "客户端离线了");
key.cancel();
self.close();
}
return read;
}
private void forwardMessage(SelectionKey key, ByteBuffer buffer) throws IOException {
for (SelectionKey selectedKey : selector.keys()) {
if (selectedKey != key && selectedKey.channel() instanceof SocketChannel) {
System.out.println("开始转发");
SocketChannel channel = (SocketChannel) selectedKey.channel();
channel.write(ByteBuffer.wrap(buffer.array()));
}
}
}
}
2.客户端
public class GroupChatClient {
private SocketChannel socketChannel;
private Selector selector;
public GroupChatClient() {
try {
socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 6666));
socketChannel.configureBlocking(false);
selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("客户端准备就绪");
} catch (IOException e) {
e.printStackTrace();
}
}
@SuppressWarnings("InfiniteLoopStatement")
public static void main(String[] args) {
GroupChatClient groupChatClient = new GroupChatClient();
ExecutorService executorService = new ThreadPoolExecutor(1, 1, 3,
TimeUnit.SECONDS, new LinkedBlockingDeque<>(5));
executorService.execute(() -> {
while (true) {
try {
groupChatClient.readMessage();
Thread.sleep(1000);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
});
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String next = scanner.next();
groupChatClient.sendMessage(next);
}
}
public void readMessage() throws IOException {
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
if (key.isReadable()) {
SocketChannel channel = (SocketChannel) key.channel();
ByteBuffer buffer = ByteBuffer.allocate(512);
channel.read(buffer);
System.out.println(new String(buffer.array()).trim());
}
iterator.remove();
}
}
public void sendMessage(String message) {
try {
socketChannel.write(ByteBuffer.wrap(message.getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
}