serverSocketChannel.accept() 返回 null

serverSocketChannel.accept() returns null

提问人:Rahul 提问时间:8/29/2023 最后编辑:Mark RotteveelRahul 更新时间:8/29/2023 访问量:28

问:

我正在尝试用Java NIO编写一个简单的客户端服务器程序。

代码如下:

package org.lb;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Set;

public class Test {
  public static void main(String[] args) throws IOException {
    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
    serverSocketChannel.bind(new InetSocketAddress(8080));
    serverSocketChannel.configureBlocking(false);

    Selector selector = Selector.open();
    serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

    while (true) {
      selector.select();
      Set<SelectionKey> selectionKeySet = selector.selectedKeys();
      for (SelectionKey selectionKey : selectionKeySet) {
        if (selectionKey.isAcceptable()) {
          SocketChannel socketChannel = serverSocketChannel.accept();
          if (socketChannel == null) {
            System.out.println("No connection...");
          } else {
            socketChannel.configureBlocking(false);
            socketChannel.register(selector, SelectionKey.OP_READ);
            System.out.println("Connection done!");
          }
        }

        if (selectionKey.isReadable()) {
          System.out.println("isReadable");
          SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
          socketChannel.close();
        }
      }
    }
  }
}

您可以看到,我只在返回 true 时调用。因此,我认为它应该始终返回一个有效的实例,但有时它也会返回 null。serverSocketChannel.accept()selectionKey.isAcceptable()serverSocketChannel.accept()SocketChannel

我正在尝试使用 Postman 发送请求,但浏览器请求也是如此。

使用 Postman 单个请求输出

Connection done!
No connection...
isReadable
Connection done!
No connection...
isReadable

我以为它打印了一次,但它打印了两次。另外,为什么要打印?Connection done!No connection...

使用 curl single 请求输出

Connection done!
isReadable
No connection...
Java NIO 无阻塞

评论

2赞 Mark Rotteveel 8/29/2023
来自 javadoc:“返回:新连接的套接字通道,如果此通道处于非阻塞模式且没有可接受的连接,则 null
0赞 Rahul 8/29/2023
我从这里可以看到的是,如果此键的通道已准备好接受新的套接字连接,则返回 true。我只在属实时才打电话。因此,它不应返回 null。isAcceptableisAcceptableserverSocketChannel.accept()isAcceptable()
1赞 Mark Rotteveel 8/29/2023
我几乎从不对 NIO 进行编程,但您不应该在处理后从集合中删除选择键吗?换句话说,假设您不删除它,即使当前没有等待,后续调用也会继续返回它。selectedKeys()
0赞 user207421 10/16/2023
@MarkRotteveel是正确的。上次的钥匙还是可以接受的。
0赞 Rahul 10/16/2023
它得到了解决,多亏了@MarkRotteveel

答: 暂无答案