2010-09-19 1 views
0

При выборе SelectableChannel c и его SelectionKey k, k.isWritable() возвращает, готов ли канал принимать вызовы write().Может ли SelectionKey.isWritable быть истинным без OP_WRITE в процентахOps()?

Однако может ли k.isWritable() возвращать true, если канал принимает записи, но OP_WRITE не установлен в процентах?

ответ

1

Нет, готовые операторы являются подмножеством интересов ops. если ключ не заинтересован в записи, селектор не будет устанавливать свою готовность к записи (что не означает, что он не может принять запись. вы можете называть write() в любое время. с write-ready, write(), скорее всего, преуспеет, но там тоже нет гарантии)

+0

Это другой вопрос, но при каких обстоятельствах (кроме соединения, которое закрывается между isWriteable() и write()), может ли ошибка записи/получить задержку? – tstenner

+0

вот что говорит SelectionKey javadoc. – irreputable

0

Существует улов, который мне стоит нескольких часов, чтобы выяснить. Рассмотрим следующий код:

SocketChannel socket = SocketChannel.open(new InetSocketAddress("127.0.0.1", 22)); 
socket.configureBlocking(false); 
Selector selector = Selector.open(); 
SelectionKey selkey = socket.register(selector, 0); 
.... 
selkey.interestOps(SelectionKey.OP_READ); 
selector.select(1000); 
System.out.println("Selecting r, return " + 
    (selector.selectedKeys().contains(selkey) && selkey.isReadable() ? "r" : "") + 
    (selector.selectedKeys().contains(selkey) && selkey.isWritable() ? "w" : "")); 

Он печатает «Выбор r, возврат w». Таким образом, iswritable() может быть истинным, пока интересуется только OP_READ. Это происходит, если OP_WRITE включен в предыдущий вызов select(), а текущий select() возвращает 0, что означает, что selkey ​​не обновляется.

Полный код доказательства находится здесь: https://gist.github.com/wuyongzheng/43cc9dc07e13124663d1. Для запуска вам нужен SSH-сервер в порту 22.

Смежные вопросы