У меня проблема с использованием Selectors.Как правильно использовать селектор NIO?
Я написал несколько тестовых кодов, чтобы попытаться создать соединение Client/Server с селектором на сервере, чтобы управлять каналами. Проблема заключается в том, что, когда селектор выбирает канал для чтения, и операция чтения обрабатывается, данные фактически не считываются.
Я разместил этот вопрос на another forum и еще не получил ответов.
Сервер:
static class Server implements Runnable {
Selector sel;
@Override
public void run() {
try {
ServerSocketChannel server = ServerSocketChannel.open();
server.socket().bind(new InetSocketAddress(5555));
server.configureBlocking(false);
sel = Selector.open();
server.register(sel, SelectionKey.OP_ACCEPT);
boolean running = true;
while(running) {
int count = sel.select();
if(sel.isOpen() && count > 0) {
Set<SelectionKey> keyset = sel.selectedKeys();
synchronized(keyset) {
Iterator<SelectionKey> i = keyset.iterator();
while(i.hasNext()) {
SelectionKey key = i.next();
i.remove();
processKey(key);
}
}
} else if(!sel.isOpen())
running = false;
}
} catch (IOException e) {
e.printStackTrace();
}
}
private void processKey(SelectionKey key) {
if(key.isValid() && key.isAcceptable()) {
try {
SocketChannel chan = ((ServerSocketChannel)key.channel()).accept();
chan.configureBlocking(false);
chan.register(sel, SelectionKey.OP_READ);
} catch (IOException e) {
e.printStackTrace();
}
}
if(key.isValid() && key.isReadable()) {
System.out.println("Read starting...");
SocketChannel chan = (SocketChannel) key.channel();
ByteBuffer buff = ByteBuffer.allocate(1024);
try {
while((chan.read(buff))>=0) {
buff.flip();
System.out.println("read some");
buff.clear();
}
chan.close();
System.out.println("Read complete");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
Клиент:
static class Client implements Runnable {
@Override
public void run() {
try {
SocketChannel chan = SocketChannel.open();
chan.connect(new InetSocketAddress("localhost", 5555));
while(!chan.finishConnect());
ByteBuffer buff = ByteBuffer.allocate(1024);
for(int i=0;i<1000;i++) {
buff.flip();
chan.write(buff);
buff.compact();
}
chan.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Вот pastebin полного исходного кода. Любые идеи были оценены.
Не похоже, что вы пишете какие-либо данные. (Существует также гонка между запуском сервера и клиента.) –
Я пытаюсь писать пустые байты. ИТ должен все же писать данные, правда? И я попытался использовать Thread.sleep(), прежде чем инициировать код клиента, и это не помогло. – bgroenks
Но вы никогда не заполняете буфер. Я думаю, что вызов 'limit (int)' должен делать это. (Отказ от ответственности: я на самом деле не делал никаких разумных программ NIO в течение десятилетия). –