gpt4 book ai didi

java - interestOps 抛出 IllegalArgumentException

转载 作者:行者123 更新时间:2023-11-29 08:08:05 25 4
gpt4 key购买 nike

我想向 map 中的所有用户发送消息。

    for (User u : _userMap.values()) {
u.getMessages().add(data);

u.getKey().interestOps(SelectionKey.OP_WRITE);
}

但是当我运行这个函数时我看到了

Exception in thread "main" java.lang.IllegalArgumentException

这一行出错

u.getKey().interestOps(SelectionKey.OP_WRITE);

getKey() 返回 SelectionKey,getMessages 返回 ArrayList,data 是一个 byte[] 数组,其中包含我使用 channel.read(buffer) 读取的消息;

更多信息:

在构造函数中我创建了 Selector

_selector = Selector.open();

我运行服务器

public void startServer() throws IOException {
while (true) {
_selector.select();

Iterator<SelectionKey> keys = _selector.selectedKeys().iterator();

while (keys.hasNext()) {
SelectionKey key = keys.next();
keys.remove();

if (!key.isValid())
continue;
if (key.isAcceptable())
accept(key);
else if (key.isReadable())
read(key);
else if (key.isWritable())
write(key);
}
}
}

我接受连接

private void accept(SelectionKey key) throws IOException {
ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
SocketChannel channel = serverChannel.accept();
channel.configureBlocking(false);

User u = new User(key);
_userMap.put(channel, u);

channel.register(_selector, SelectionKey.OP_READ);
}

在读取消息时的读取函数中,每个循环都有这个。但是当只有一个用户时,我将 interestOps 移到它工作的循环后面。

        //u.getKey().interestOps(SelectionKey.OP_WRITE);
}
key.interestOps(SelectionKey.OP_WRITE);

完整的读写功能:

private void read(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();

ByteBuffer buffer = ByteBuffer.allocate(2048);
int read = -1;

try {
read = channel.read(buffer);
} catch (Exception e) {
e.printStackTrace();
}

if (read == -1) {
_userMap.remove(channel);

channel.close();
key.cancel();

return;
}

byte[] data = new byte[read];

System.arraycopy(buffer.array(), 0, data, 0, read);

/// WYSyŁA DO WSZYSTKICH. usunąć

for (User u : _userMap.values()) {
u.getMessages().add(data);

u.getKey().interestOps(SelectionKey.OP_WRITE);
}
//key.interestOps(SelectionKey.OP_WRITE);

///////
}

private void write(SelectionKey key) throws IOException {
SocketChannel channel = (SocketChannel) key.channel();

ArrayList<byte[]> msg = _userMap.get(channel).getMessages();
Iterator<byte[]> i = msg.iterator();

while (i.hasNext()) {
byte[] item = i.next();
i.remove();

channel.write(ByteBuffer.wrap(item));
}

key.interestOps(SelectionKey.OP_READ);
}

解决方案:

我现在无法回答我自己的问题,所以把它放在这里:

accept 方法中的 SelectionKey 有点缺陷。我试图用读取方法中的新 key 替换它并且它有效。所以在用户类中我不再保留 SelectionKey var,现在我保留 SocketChannel。 SocketChannel 有 keyFor 方法,所以当我有选择器时我可以获得 key

        u.getChannel().keyFor(_selector).interestOps(SelectionKey.OP_WRITE);

最佳答案

听起来可能与记录的完全一样:

Throws
IllegalArgumentException - If a bit in the set does not correspond to an operation that is supported by this key's channel, that is, if set & ~(channel().validOps()) != 0

虽然不了解更多关于相关 channel 的信息,但很难知道为什么会出现这种情况......

关于java - interestOps 抛出 IllegalArgumentException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9810087/

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