使用Selector发出写入超时问题

时间:2017-08-09 16:45:51

标签: java nio socketchannel

我试图通过使用Selector:

为SocketChannel添加写超时
public int write(ByteBuffer buf, long timeout, SocketChannel socketChannel, Selector selector) {
    int written = socketChannel.write(buf);
    if (written == 0) {
        SelectionKey selectionKey = socketChannel.register(selector, SelectionKey.OP_WRITE);
        try {
            selector.select(timeout);
            if (Thread.interrupted()) {
                throw new InterruptedIOException();
            }
            written = socketChannel.write(buf);
        } finally {
            selectionKey.cancel();
        }
    }
    return written;
}

计划是重复使用选择器并在每次超时后取消注册。但显然我得到了相同的selectionKey,如果我调用我的方法两次并且根本无法写入,则之前取消了。在第二次方法调用期间调用register时,这会导致CancelledKeyException。在第一次被取消之后,我想我会得到一个新的selectionKey。

那我该怎么做?我想在寄存器之前或取消之后调用selectNow(),为了清除已取消的键会解决它但是看起来很奇怪,有更好的方法吗?

0 个答案:

没有答案