下面是客户端的代码, 用的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();}
}
}