JAVA NIO 实现群聊
一、群聊服务器
package com.dashu.netty.group_chat;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
public class GroupChatServer {
private Selector selector;
private ServerSocketChannel serverSocketChannel;
private static final int PORT = 6666;
public GroupChatServer() {
try {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
InetSocketAddress inetSocketAddress = new InetSocketAddress(PORT);
serverSocketChannel.socket().bind(inetSocketAddress);
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
} catch (Exception e) {
e.printStackTrace();
}
}
public void listen() {
try {
while (true) {
int count = selector.select();
if (count > 0) {
Iterator<SelectionKey> selectionKeyIterator = selector.selectedKeys().iterator();
while (selectionKeyIterator.hasNext()) {
SelectionKey selectionKey = selectionKeyIterator.next();
if (selectionKey.isAcceptable()) {
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println(socketChannel.getRemoteAddress() + "上线了");
}
if (selectionKey.isReadable()) {
readData(selectionKey);
}
selectionKeyIterator.remove();
}
} else {
System.out.println("等待...");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void readData(SelectionKey selectionKey) {
SocketChannel socketChannel = null;
try {
socketChannel = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
int count = socketChannel.read(byteBuffer);
if (count > 0) {
String message = new String(byteBuffer.array());
System.out.println(message.trim());
sendInfoToOtClients(message, socketChannel);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void sendInfoToOtClients(String message, SocketChannel socketChannel) {
for (SelectionKey selectionKey : selector.keys()) {
Channel channel = selectionKey.channel();
if (channel instanceof SocketChannel && channel != socketChannel) {
SocketChannel sc = (SocketChannel) channel;
ByteBuffer byteBuffer = ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8));
try {
sc.write(byteBuffer);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
GroupChatServer groupChatServer = new GroupChatServer();
System.out.println("服务器启动,开始监听客户端请求...");
groupChatServer.listen();
}
}
二、客户端
package com.dashu.netty.group_chat;
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.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Scanner;
public class GroupChatClient {
private final String HOST = "127.0.0.1";
private final int PORT = 6666;
private Selector selector;
private SocketChannel socketChannel;
private String username;
public GroupChatClient() {
try {
selector = Selector.open();
InetSocketAddress inetSocketAddress = new InetSocketAddress(HOST, PORT);
socketChannel = SocketChannel.open(inetSocketAddress);
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("请输入用户名:");
Scanner scanner = new Scanner(System.in);
username = scanner.nextLine();
System.out.println(username + " 进入群聊...");
} catch (Exception e) {
e.printStackTrace();
}
}
public void sendInfo(String message) {
message = username + ":" + message;
try {
socketChannel.write(ByteBuffer.wrap(message.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
e.printStackTrace();
}
}
public void readInfo() {
try {
int count = selector.select();
if (count > 0) {
Iterator<SelectionKey> selectionKeyIterator = selector.selectedKeys().iterator();
while (selectionKeyIterator.hasNext()) {
SelectionKey selectionKey = selectionKeyIterator.next();
if (selectionKey.isReadable()) {
SocketChannel sc = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
sc.read(byteBuffer);
String message = new String(byteBuffer.array());
System.out.println(message.trim());
}
selectionKeyIterator.remove();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
GroupChatClient groupChatClient = new GroupChatClient();
new Thread() {
@Override
public void run() {
while (true) {
groupChatClient.readInfo();
try {
Thread.sleep(3000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}.start();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入信息:");
while (scanner.hasNextLine()) {
String s = scanner.nextLine();
groupChatClient.sendInfo(s);
System.out.println("请输入信息:");
}
}
}
三、效果图
1、服务器
2、客户端01
3、客户端02