私はマップ内のすべてのユーザーにメッセージを送信します。interestOps throw IllegalArgumentException
for (User u : _userMap.values()) {
u.getMessages().add(data);
u.getKey().interestOps(SelectionKey.OP_WRITE);
}
が、私はこの機能を実行するwhene私はこのラインスレッド "メイン" java.lang.IllegalArgumentExceptionが
に
例外を参照してくださいエラー
u.getKey().interestOps(SelectionKey.OP_WRITE);
のgetKeyを作ります()はSelectionKeyを返し、getMessagesはArrayListを返し、dataはmesを持つbyte []配列です私はchannel.read(buffer)を使って読みました。
MORE INFO:私は、サーバー
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); } } }
を実行して、私はセレクタ
_selector = Selector.open();
作るコンストラクタで
私が読んwhene私は、読み取り機能で接続
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); }
を受け入れますmes私はこれをループ毎に持っています。しかし、私は1人のユーザーであり、私はinterestOpsをループの後ろに置くだけでそれを動かす。
//u.getKey().interestOps(SelectionKey.OP_WRITE); } key.interestOps(SelectionKey.OP_WRITE);
完全な読み取りおよび書き込み機能:
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:
私は今、自分の質問に答えるので、ここでそれを置くことはできません。
とSelectionKeyの中方法がある受け入れます少し身障者。私はそれをreadメソッドで新しいキーに置き換えようとしました。だからUserクラスでは、SelectionKey変数をこれ以上保持しないので、今はSocketChannelを保持します。 SocketChannelはkeyFor方法を持っているので、私はセレクタを持ってwheneそれはおそらく正確に文書化されているようだように私は
u.getChannel().keyFor(_selector).interestOps(SelectionKey.OP_WRITE);
javadoc:http:// docsを読んだことがありますか?oracle.com/javase/6/docs/api/java/nio/channels/SelectionKey.html#interestOps(int) –
はい、それはわかりません。 – user1248092
チャンネルを閉じると、キーがキャンセルされます。あなたはそれを自分で行う必要はありません。 – EJP