Java基于NIO实现群聊模式攻略
简介
Java NIO(New I/O)是Java 1.4版本引入的一组用于高效处理I/O操作的API。使用Java NIO,我们可以实现非阻塞的、事件驱动的I/O操作,这对于实现群聊模式非常有用。在本攻略中,我们将使用Java NIO来实现一个简单的群聊程序。
步骤
步骤1:创建服务器端
首先,我们需要创建一个服务器端来接收客户端的连接,并将接收到的消息广播给所有连接的客户端。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
public class Server {
private Selector selector;
private ServerSocketChannel serverSocketChannel;
private ByteBuffer buffer = ByteBuffer.allocate(1024);
public void start(int port) throws IOException {
selector = Selector.open();
serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.bind(new InetSocketAddress(port));
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println(\"Server started on port \" + port);
while (true) {
selector.select();
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
if (key.isAcceptable()) {
acceptConnection(key);
} else if (key.isReadable()) {
broadcastMessage(key);
}
}
}
}
private void acceptConnection(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel clientChannel = serverChannel.accept();
clientChannel.configureBlocking(false);
clientChannel.register(selector, SelectionKey.OP_READ);
System.out.println(\"New client connected: \" + clientChannel.getRemoteAddress());
}
private void broadcastMessage(SelectionKey key) throws IOException {
SocketChannel clientChannel = (SocketChannel) key.channel();
buffer.clear();
int bytesRead = clientChannel.read(buffer);
if (bytesRead == -1) {
clientChannel.close();
return;
}
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String message = new String(bytes);
System.out.println(\"Received message: \" + message);
for (SelectionKey selectionKey : selector.keys()) {
Channel channel = selectionKey.channel();
if (channel instanceof SocketChannel && channel != clientChannel) {
SocketChannel destChannel = (SocketChannel) channel;
destChannel.write(ByteBuffer.wrap(bytes));
}
}
}
public static void main(String[] args) throws IOException {
Server server = new Server();
server.start(8080);
}
}
步骤2:创建客户端
接下来,我们需要创建一个客户端来连接服务器,并发送和接收消息。
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.util.Scanner;
public class Client {
private SocketChannel socketChannel;
private ByteBuffer buffer = ByteBuffer.allocate(1024);
public void start(String serverHost, int serverPort) throws IOException {
socketChannel = SocketChannel.open();
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress(serverHost, serverPort));
while (!socketChannel.finishConnect()) {
// 等待连接完成
}
System.out.println(\"Connected to server: \" + socketChannel.getRemoteAddress());
new Thread(() -> {
try {
while (true) {
buffer.clear();
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1) {
socketChannel.close();
return;
}
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String message = new String(bytes);
System.out.println(\"Received message: \" + message);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
Scanner scanner = new Scanner(System.in);
while (true) {
String message = scanner.nextLine();
if (message.equalsIgnoreCase(\"exit\")) {
socketChannel.close();
break;
}
buffer.clear();
buffer.put(message.getBytes());
buffer.flip();
socketChannel.write(buffer);
}
}
public static void main(String[] args) throws IOException {
Client client = new Client();
client.start(\"localhost\", 8080);
}
}
示例说明
示例1:运行服务器端
Server server = new Server();
server.start(8080);
示例2:运行客户端
Client client = new Client();
client.start(\"localhost\", 8080);
在示例2中,客户端将连接到本地主机的8080端口,并可以发送和接收消息。在服务器端示例1中,服务器将监听8080端口,并将接收到的消息广播给所有连接的客户端。
请注意,示例中的代码仅为演示目的,可能需要根据实际需求进行修改和扩展。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java基于NIO实现群聊模式 - Python技术站