nio实现多路复用代码
时间: 2024-05-12 11:21:16 浏览: 108
以下是基于nio实现多路复用的示例代码:
```java
import java.io.IOException;
import java.net.InetSocketAddress;
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.util.Iterator;
import java.util.Set;
public class NioMultiplexingServer {
private Selector selector;
public void init(int port) throws IOException {
// 创建selector
selector = Selector.open();
// 创建ServerSocketChannel
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.configureBlocking(false);
// 绑定端口
serverSocketChannel.socket().bind(new InetSocketAddress(port));
// 将ServerSocketChannel注册到selector上,并监听OP_ACCEPT事件
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
System.out.println("Server started at port " + port);
// 循环处理selector上的事件
while (true) {
// 阻塞等待事件发生
int readyChannels = selector.select();
if (readyChannels == 0) {
continue;
}
// 处理事件
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if (key.isAcceptable()) {
// 处理OP_ACCEPT事件
handleAccept(key);
} else if (key.isReadable()) {
// 处理OP_READ事件
handleRead(key);
}
keyIterator.remove();
}
}
}
private void handleAccept(SelectionKey key) throws IOException {
// 获取ServerSocketChannel
ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();
// 接受连接
SocketChannel socketChannel = serverSocketChannel.accept();
socketChannel.configureBlocking(false);
// 将SocketChannel注册到selector上,并监听OP_READ事件
socketChannel.register(selector, SelectionKey.OP_READ);
System.out.println("Connection accepted: " + socketChannel.getRemoteAddress());
}
private void handleRead(SelectionKey key) throws IOException {
// 获取SocketChannel
SocketChannel socketChannel = (SocketChannel) key.channel();
// 读取数据
ByteBuffer buffer = ByteBuffer.allocate(1024);
int bytesRead = socketChannel.read(buffer);
if (bytesRead == -1) {
// 连接已关闭
socketChannel.close();
System.out.println("Connection closed: " + socketChannel.getRemoteAddress());
return;
}
// 处理数据
buffer.flip();
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
String message = new String(bytes);
System.out.println("Message received from " + socketChannel.getRemoteAddress() + ": " + message);
// 回复客户端
ByteBuffer responseBuffer = ByteBuffer.wrap(("Received message: " + message).getBytes());
socketChannel.write(responseBuffer);
}
public static void main(String[] args) throws IOException {
NioMultiplexingServer server = new NioMultiplexingServer();
server.init(8080);
}
}
```
上述代码实现了一个简单的nio多路复用服务器,其中:
1. 初始化方法中创建了一个Selector和一个ServerSocketChannel,并将ServerSocketChannel注册到selector上,监听OP_ACCEPT事件;
2. 循环处理selector上的事件,阻塞等待事件发生;
3. 对于每个事件,根据事件类型进行处理,处理完毕后从selector的selectedKeys集合中移除该事件。
在handleAccept和handleRead方法中,分别处理了OP_ACCEPT和OP_READ事件:
1. handleAccept方法中,获取ServerSocketChannel并接受连接,将SocketChannel注册到selector上,监听OP_READ事件;
2. handleRead方法中,获取SocketChannel并读取数据,处理数据并回复客户端。
通过以上代码,我们实现了一个简单的nio多路复用服务器,可以同时处理多个连接请求。
阅读全文