本文主要是介绍【Android】Java NIO(New I/O)的`Selector`类来实现非阻塞的Socket监听,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
如果你不想使用循环来监听客户端的连接和数据,你可以使用Java NIO(New I/O)的Selector
类来实现非阻塞的Socket监听。Selector
类提供了一种选择一组已经就绪的通道的机制,这样你就不需要使用循环来等待连接和数据。
以下是使用Selector
类的示例代码:
private ServerSocketChannel serverSocketChannel;
private Selector selector;private void startServer() throws IOException {serverSocketChannel = ServerSocketChannel.open();serverSocketChannel.configureBlocking(false);serverSocketChannel.socket().bind(new InetSocketAddress(8888));selector = Selector.open();serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);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()) {handleAcceptableKey(key);} else if (key.isReadable()) {handleReadableKey(key);}keyIterator.remove();}}
}private void handleAcceptableKey(SelectionKey key) throws IOException {ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();SocketChannel clientChannel = serverChannel.accept();clientChannel.configureBlocking(false);clientChannel.register(selector, SelectionKey.OP_READ);Log.d("Server", "设备已连接");
}private void handleReadableKey(SelectionKey key) throws IOException {SocketChannel channel = (SocketChannel) key.channel();ByteBuffer buffer = ByteBuffer.allocate(1024);int bytesRead = channel.read(buffer);if (bytesRead == -1) {channel.close();Log.d("Server", "设备已断开连接");return;}buffer.flip();byte[] data = new byte[buffer.limit()];buffer.get(data);String receivedData = new String(data);Log.d("Server", "接收到数据:" + receivedData);// 处理接收到的数据// 回复客户端ByteBuffer responseBuffer = ByteBuffer.wrap(("已接收到数据:" + receivedData).getBytes());channel.write(responseBuffer);
}
在上面的代码中,我们首先创建一个ServerSocketChannel
对象,并将其配置为非阻塞模式。然后,我们将ServerSocketChannel
绑定到指定的端口,并将其注册到Selector
中,以便监听客户端连接。
在while
循环中,我们使用selector.select()
方法来选择已经就绪的通道。如果没有就绪的通道,我们可以继续等待。一旦有通道就绪,我们使用selector.selectedKeys()
方法获取已选择的键集合,并使用迭代器遍历这些键。
在迭代器循环中,我们根据键的类型判断通道是否可接受连接或可读取数据。如果是可接受连接的通道,我们使用handleAcceptableKey()
方法处理。如果是可读取数据的通道,我们使用handleReadableKey()
方法处理。
在handleAcceptableKey()
方法中,我们使用serverChannel.accept()
方法来接受客户端连接,并将客户端通道注册到Selector
中,以便监听客户端发送的数据。
在handleReadableKey()
方法中,我们首先读取客户端发送的数据,并将其存储在ByteBuffer
中。如果读取到的字节数为-1,表示客户端断开连接,我们关闭通道并在日志中打印出"设备已断开连接"。如果读取到有效的数据,我们可以在代码中处理这些数据,并通过通道向客户端发送回复。
请注意,这只是一个使用Selector
的简单示例代码。你需要根据你的实际需求进行适当的修改和优化。
希望这可以解决你的问题!
这篇关于【Android】Java NIO(New I/O)的`Selector`类来实现非阻塞的Socket监听的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!