写入通道后,Java Selector返回带有OP_READ的SelectionKey,而无需在无限循环中的数据
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了写入通道后,Java Selector返回带有OP_READ的SelectionKey,而无需在无限循环中的数据,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2861字,纯文字阅读大概需要5分钟。
内容图文
我的代码出了问题:我用Selector编写了简单的SocketChannel客户端,启动后成功从服务器读取消息(服务器发送事件).但是在写入socket(参见main方法)之后,选择器开始在infinyty循环中返回可读套接字,handleKey返回-1个字节readed,因此选择器所有时间都返回OP_READ SelectionKey而没有数据用于读取.
对不起我的英语不好.
谢谢.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
public class SelectorTest
{
public SelectorTest() throws IOException {
selector = Selector.open();
}
private void runSelector() {
new Thread(new Runnable() {
public void run()
{
alive = true;
try {
while(alive) {
System.out.println("Selector started...");
selector.select();
Iterator<SelectionKey> keyIter = selector.selectedKeys().iterator();
while(keyIter.hasNext()) {
SelectionKey key = keyIter.next();
keyIter.remove();
handleKey(key);
}
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}).start();
}
private void handleKey(SelectionKey key) throws IOException {
SocketChannel chan = (SocketChannel) key.channel();
System.out.println("Processing selected...");
if(key.isConnectable()) {
System.out.println("Connecting ...");
if(chan.finishConnect()) {
key.interestOps(SelectionKey.OP_READ);
} else {
key.channel();
}
} else if(key.isReadable()) {
System.out.println("Processing reading...");
ByteBuffer buf = ByteBuffer.allocate(1024);
int readedBytes = chan.read(buf);
System.out.println("Readed: " + readedBytes);
buf.flip();
for(byte b : buf.array()) {
System.out.print((char) b);
}
} else if(key.isWritable()) {
System.out.println("Finishing writing...");
key.interestOps(SelectionKey.OP_READ);
}
}
public static void main(String[] args) throws IOException {
SocketChannel channel = SocketChannel.open();
channel.configureBlocking(false);
channel.connect(new InetSocketAddress("t1.sis.lan", 6001));
SelectorTest ds = new SelectorTest();
ds.runSelector();
channel.register(ds.selector, SelectionKey.OP_CONNECT);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
for(;;) {
String line = in.readLine();
if(line==null) break;
if(line.toLowerCase().equals("bye")) break;
if (line.toLowerCase().equals("write")) {
String command = "GET_STREAMS\r\n\0";
ByteBuffer buf = ByteBuffer.allocate(1024);
buf.put(command.getBytes());
buf.flip();
channel.write(buf);
}
System.out.println("echo: "+line); // is it alive check
}
ds.alive = false;
ds.selector.wakeup();
channel.close();
}
private Selector selector;
private boolean alive;
}
解决方法:
read()在EOS返回-1,你完全忽略了它.当您获得EOS时,您必须关闭频道或至少取消注册对OP_READ的兴趣.否则,当你正在做的时候,你将永远得到另一个OP_READ和另一个-1.与上面的注释相反,read()在空读取时返回零.你可以忽略它,如果你只读isReadable(),你甚至不会看到它,除非你在循环中读取,但你不能忽略EOS.
内容总结
以上是互联网集市为您收集整理的写入通道后,Java Selector返回带有OP_READ的SelectionKey,而无需在无限循环中的数据全部内容,希望文章能够帮你解决写入通道后,Java Selector返回带有OP_READ的SelectionKey,而无需在无限循环中的数据所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。