セレクタの使用に問題があります。NIOセレクタの使い方は?
チャネルを管理するために、サーバー側のセレクタでクライアント/サーバー接続を作成しようとするテストコードを書きました。問題は、セレクタが読み込み元のチャネルを選択し、読み込み操作が処理されたときに、実際にデータが読み込まれないことです。
この質問を投稿した投稿者: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です。どんな洞察も高く評価されます。
あなたはデータを書いているようには見えません。 (サーバーとクライアントを起動する間に競争もあります) –
空のバイトを書き込もうとしています。 ITはまだデータを正しく書き込む必要がありますか?クライアントコードを開始する前にThread.sleep()を使用しようとしましたが、それは役に立ちませんでした。 – bgroenks
しかし、決してバッファーを埋めることはありません。 'limit(int)'の呼び出しはそれを行うべきだと私は思います。 (免責事項:私は実際に何十年もの間、賢明なNIOプログラミングを行っていない) –