interestOps throws IllegalArgumentException

北慕城南 提交于 2020-04-30 07:34:29

问题


I wand send a message to all User in map.

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

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

but whene I run this function I see

Exception in thread "main" java.lang.IllegalArgumentException

this line make error

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

getKey() returns SelectionKey, getMessages returns ArrayList, data is a byte[] array with message I read using channel.read(buffer);

MORE INFO:

In a constructor I make Selector

_selector = Selector.open();

I run server

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);
        }
    }
}

I accept connection

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);
}

In read function whene I read message I have this for each loop. But whene is one user and I move line with interestOps just behind loop it works.

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

Full read and write function:

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);
}

SOLUTION:

I can't answer my own question now, so put it here:

SelectionKey in accept method is a little handicapped. I tried to replace it with new key in read method and it works. So in User class I don't keep SelectionKey var any more, now I keep SocketChannel. SocketChannel have keyFor method, so whene I have selector I can get key

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

回答1:


Sounds like it's probably exactly as documented:

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

It's hard to know why that's the case without knowing more about the channel in question though...




回答2:


I would say your user map contains the ServerSocketChannel as well as accepted SocketChannels. You can't set OP_WRITE on a ServerSocketChannel.

I don't know what you mean by 'handicapped'.



来源:https://stackoverflow.com/questions/9810087/interestops-throws-illegalargumentexception

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!