相关代码 -- 注意 Instructions 只是一个类,其中包含多个将对数据进行操作的方法。创建一个新线程对读取的数据进行操作。
阅读主题:
while(true) {
System.out.println(".");
if(selector.select(500) == 0)
continue;
System.out.println("processing read");
for(SelectionKey sk : selector.keys()) {
Instructions ins = myHashTable.get(sk);
if(ins == null) {
myHashTable.put(sk, new Instructions(sk));
ins = myHashTable.get(sk);
}
ins.readChannel();
}
}
阅读 channel
public void readChannel() {
BufferedReader reader = new BufferedReader(Channels.newReader((ReadableByteChannel) this.myKey.channel(), "UTF-8"));
Worker w = new Worker(this, reader.readLine());
(new Thread(w)).start();
}
然后新线程调用更多的Instructions
方法。
当 ins 函数完成时,它可能写入一个 Writer:
Writer out = Channels.newWriter((WritableByteChannel) key.channel(), "UTF-8");
out.write(output);
out.flush();
我可以确认我的客户端(一个 flash 电影),然后接收并处理输出。
最后,w
退出。
从客户端接收到第一条消息并成功处理后,READ THREAD
循环不再处理更多消息。我相信 key 已在选择器中注册并准备好读取。我已经通过循环所有键来检查它们是否可以通过 channel 上的 isReadable & isRegistered 读取,并且结果在所有情况下都是正确的。但是,当从客户端发送第二条消息时,我在读取线程中看到的唯一响应是“.”。字符不是每半秒打印一次,而是持续更快。那么,我相信数据在 channel 中,但由于某种原因,选择器没有选择任何键。
谁能帮帮我?
最佳答案
我认为您在这里遗漏了几点。
- 首先,您应该在 for 循环中使用 selector.selectedKeys()
正如 Vijay 所提到的。 - 应该从 selectedKeys 中删除 key 处理 key 后。否则 key 不会 自动删除,因此选择器甚至可能会连续旋转 如果有一个键设置了感兴趣的操作位。 (这可能是 你的问题)。
- 最后,我们应该对 channel 如果 channel 已准备就绪。即,仅当 isReadable() 返回 true 并尝试仅在 isWritable() 为 真的。不要忘记验证 key 。
关于Java Selector NIO读取问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1477306/