nonblocking socketchannel是否准备好?

gadmyth 2009-11-03 01:16:48
下面是客户端的代码, 用的nonblocking模式, 将一个能读能写的socketChannel注册到一个selector上, 且将这个channel绑定到一个ByteBuffer上. 现在出现的问题是, 当这个channel与服务器端连接好后, selector会select到这个channel已经准备好, 于是让channel把数据写给服务器端; 但后面循环中, selector还是select到这个channel是准备好的状态, 但是我已经把数据都写给服务器端了, 凭什么selector又判断channel的状态是准备好写的呢, 不解! 另外, 这个channel是能读能写的, 为什么seletor没有判断出channel是能读的呢?(在if(key.isReadable()){...}里的打印语句没有出来)

不知道selector的select的原理到底是什么, java i/o这本书上也只是说它可以判断出channel是否准备好, 但具体的细节又是什么呢? 谢谢


public class SocketChannelClient {
public static void main(String... args) {
try {
final Selector selector = Selector.open();
SocketAddress address = new InetSocketAddress("127.0.0.1", 8888);
final SocketChannel channelI = SocketChannel.open(address);
channelI.configureBlocking(false);
ByteBuffer buff = ByteBuffer.wrap("123456".getBytes());
channelI.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, buff);

/*
new Thread() {
public void run(){
try{Thread.sleep(5000);}catch(Exception e){e.printStackTrace();}
System.out.println("fuck");
channelI.keyFor(selector).interestOps(SelectionKey.OP_WRITE | SelectionKey.OP_READ);
}
}.start();*/

while(true) {
selector.select();
Set keys = selector.selectedKeys();
System.out.println("keys size: " + keys.size());
Iterator it = keys.iterator();
while(it.hasNext()) {
SelectionKey key = (SelectionKey)it.next();
System.out.println("\tkeys size: " + keys.size());
if(key.isWritable()){
//System.out.println("writable " + Math.random());
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = (ByteBuffer)key.attachment();
if(!buffer.hasRemaining()) {
buffer.rewind();
//buffer.position(0);
/buffer.limit(0);
}
else {
channel.write(buffer);
//key.interestOps(SelectionKey.OP_READ);
//buffer.clear();
//key.cancel();
}
}
if(key.isReadable()){
System.out.println("readable");
SocketChannel channel = (SocketChannel)key.channel();
ByteBuffer buffer = ByteBuffer.allocate(6);
channel.read(buffer);
System.out.println(new String(buffer.array()));
}
it.remove();
}
//System.out.println("out of inner loop: " + Math.random());
}
}
catch(Exception e){e.printStackTrace();}
}
}
...全文
69 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
KKluxKlan 2012-02-23
  • 打赏
  • 举报
回复
我测试了下关于非阻塞通信程序,发现selection.isReadable()只有在客户端发送数据过来才为true;而selectionKey.iswritable()在客户端与服务器联通后,一直是为true的. 这里可能就是表示连接的客户端socket通道支持写入,所以它一直为true.
gadmyth 2009-11-03
  • 打赏
  • 举报
回复
看来这帖要沉了

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧