NIO 为什么会一直有读事件

ttxuejava 2016-07-13 06:29:59

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

/**
* 在非阻塞模式下、只需要启动一个线程、就能同时处理3件事
* 1、接收客户请求
* 2、接收客户发送的数据
* 3、向客户发回相应数据
*/
public class Server {
private int port = 8000;
private Selector selector = null;
private ServerSocketChannel serverSocketChannel = null;

public Server() throws IOException{
selector = Selector.open();//创建一个Selector对象
serverSocketChannel = ServerSocketChannel.open();//创建一个ServerSocketChannel对象
serverSocketChannel.configureBlocking(false);//设置工作模式为非阻塞模式
serverSocketChannel.socket().bind(new InetSocketAddress(port));//把服务器进程与本地端口绑定
}

public void service() throws IOException{
serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

while(selector.select()>0){
Set<SelectionKey> readKey = selector.selectedKeys();//获得Selector的selected-key集合
Iterator<SelectionKey> it = readKey.iterator();

while(it.hasNext()){
SelectionKey key = null;
try {
key = (SelectionKey) it.next();
it.remove();
if(key.isAcceptable()){
ServerSocketChannel ssc = (ServerSocketChannel)key.channel();
SocketChannel socketChannel = ssc.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ|SelectionKey.OP_WRITE);
}

if(key.isReadable()){
System.out.println("read...");
}

if(key.isWritable()){
System.out.println("write...");
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

public static void main(String[] args) throws IOException {
new Server().service();
}
}



public class Test {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("127.0.0.1",8000);
}
}


打印结果:
read...
write...
read...
write...
read...
write...
read...
write...
read...
。。。。。。。


客户端并没有向服务端发送任何数据 为什么一直会有读事件









...全文
314 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
另外,在使用 NIO 时,不要注册写事件,因为在通道中 99% 以上的时间是可写的,如果注册了会死循环地进入可写事件流。一般在真正需要向通道写入数据时临时注册写事件,在数据写完后立马注销写事件。
  • 打赏
  • 举报
回复
if(key.isReadable()){ System.out.println("read..."); } 因为你没有把 Channel 中的数据读出来啊,只是打印了个不相干的东西。
lpq29743 2016-07-13
  • 打赏
  • 举报
回复
http://stackoverflow.com/questions/4139300/socketchannel-fires-isreadable-but-nothing-to-read 我想这个应该能解决你的问题

62,628

社区成员

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

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