0 时,服务器套接字始终位于选定的键集中,即使没-6ren">
gpt4 book ai didi

java - 当没有传入连接时 SelectionKey.isAcceptable() 返回 "true"

转载 作者:行者123 更新时间:2023-12-01 22:42:38 25 4
gpt4 key购买 nike

我正在使用 Java NIO 用 Ja​​va 编写一个聊天服务器。服务器毫无问题地接受连接,但任何时候 select() 在第一个客户端之后返回 > 0 时,服务器套接字始终位于选定的键集中,即使没有挂起的连接也是如此。即使 select() 返回 1,选定的键集也将有 2 个元素并包括服务器套接字。这会导致accept()返回null。

任何帮助将不胜感激。

主循环:

public void start() throws IOException {
Set<SelectionKey> keys;
Iterator<SelectionKey> keyIterator;
this.keepGoing = true;

while (keepGoing) {
int readyChannels = this.selector.select();

if (readyChannels == 0)
{
continue;
}

keys = this.selector.selectedKeys();
keyIterator = keys.iterator();

while (keyIterator.hasNext())
{
SelectionKey currentKey = keyIterator.next();

if (currentKey.isAcceptable())
{
addClient(currentKey);
}
if (currentKey.isReadable())
{
readSock(currentKey);
}
if (currentKey.isWritable())
{
// write data to the buffer and remove OP_WRITE
}
}
}

}

服务器初始化代码:

public Server(int port) {

this.listenPort = port;

try
{
this.selector = Selector.open();
this.listenChannel = ServerSocketChannel.open();
this.listenChannel.socket().bind(new InetSocketAddress(this.listenPort), BACKLOG);
this.listenChannel.configureBlocking(false);
this.listenChannel.register(this.selector, SelectionKey.OP_ACCEPT);
}
catch (IOException e)
{
System.out.println("Server could not initialise: " + e.getMessage());
}

this.users = new HashMap<>();
}

addClient 方法:

private void addClient(SelectionKey key) throws IOException {
ServerSocketChannel acceptSocket = (ServerSocketChannel) key.channel();
SocketChannel newClient = acceptSocket.accept();
SelectionKey clientKey;

// Set the new client to non-blocking mode and add to the selector
newClient.configureBlocking(false);
clientKey = newClient.register(this.selector, SelectionKey.OP_READ);

// Add a new key-user pair to the user list
this.users.put(clientKey, new User());

// Attach a buffer for reading the packets
clientKey.attach(new PacketBuffer(newClient));
}

最佳答案

您必须在 keyIterator.next() 之后调用 keyIterator.remove(),或者在循环结束时清除选定的键集。选择器不会从该集中删除键,这取决于您。但您还需要注意,accept() 在非阻塞模式下可以返回 null,并相应地进行防御性编程。

关于java - 当没有传入连接时 SelectionKey.isAcceptable() 返回 "true",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25906549/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com