MST

星途 面试题库

面试题:Java NIO非阻塞模式下如何实现基本的Socket通信

在Java NIO的非阻塞模式下,简述使用Selector、SocketChannel等实现一个简单的客户端与服务器端Socket通信的步骤及关键代码。
12.2万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

服务器端步骤及关键代码

  1. 打开ServerSocketChannel并绑定端口
ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
serverSocketChannel.socket().bind(new InetSocketAddress(8888));
serverSocketChannel.configureBlocking(false);
  1. 创建Selector并注册ServerSocketChannel
Selector selector = Selector.open();
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
  1. 轮询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()) {
            // 处理新连接
            ServerSocketChannel server = (ServerSocketChannel) key.channel();
            SocketChannel client = server.accept();
            client.configureBlocking(false);
            client.register(selector, SelectionKey.OP_READ);
        } else if (key.isReadable()) {
            // 处理读事件
            SocketChannel client = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            int bytesRead = client.read(buffer);
            if (bytesRead > 0) {
                buffer.flip();
                byte[] data = new byte[buffer.limit()];
                buffer.get(data);
                System.out.println("Received: " + new String(data));
            }
        }
        keyIterator.remove();
    }
}

客户端步骤及关键代码

  1. 打开SocketChannel并连接服务器
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("localhost", 8888));
socketChannel.configureBlocking(false);
  1. 创建Selector并注册SocketChannel
Selector selector = Selector.open();
socketChannel.register(selector, SelectionKey.OP_CONNECT);
  1. 处理连接就绪事件
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.isConnectable()) {
            SocketChannel client = (SocketChannel) key.channel();
            if (client.isConnectionPending()) {
                client.finishConnect();
            }
            client.register(selector, SelectionKey.OP_WRITE);
        } else if (key.isWritable()) {
            // 处理写事件
            SocketChannel client = (SocketChannel) key.channel();
            ByteBuffer buffer = ByteBuffer.wrap("Hello, Server!".getBytes());
            client.write(buffer);
            client.close();
        }
        keyIterator.remove();
    }
}