首页 新闻 会员 周边 捐助

只发送了一条16字节的消息,JavaNIO Selector.select()在建立连接后,一直获取到读事件

1
悬赏园豆:100 [已关闭问题] 关闭于 2018-04-11 13:34

我使用NIO来接收一段消息,连接上后,将获取到的SocketChannel绑定到Selector上
监听读事件。

有读事件时,将SelectionKey提交给一个线程池中的线程异步处理


这个时候,我通过单步运行调试和添加system.out发现了一些问题,看到Selector一直select到有一个通道有读事件,一直重复执行selectionKey.isReadable() 下的内容,即Selector.select()一直返回1

初步怀疑,是不是因为系统认为我没有处理这个读事件?

system.out的部分重复内容:

 

接收部分代码:

 public void StartServer(){
        try {
            System.out.println("Trying to Start the Server... ...");
            ServerSocketChannel serverChannel = ServerSocketChannel.open();
            serverChannel.bind(new InetSocketAddress(1234));
            serverChannel.configureBlocking(false);
            System.out.println("Success to Start the Server... ...");
            threadPoolExecutor.execute(new QueueListener(MessageQueue));
            Selector selector = Selector.open();
            SelectionKey key = serverChannel.register(selector, SelectionKey.OP_ACCEPT);
            while (true) {
                int select = selector.select();
                if (select > 0) {
                    Set<SelectionKey> selectedKeys = selector.selectedKeys();
                    Iterator<SelectionKey> iterator = selectedKeys.iterator();
                    while (iterator.hasNext()) {
                        SelectionKey selectionKey = iterator.next();
                        iterator.remove();
                        // 接收连接请求
                        if (selectionKey.isAcceptable()) {
                            ServerSocketChannel channel = (ServerSocketChannel) selectionKey
                                    .channel();
                            SocketChannel socketChannel = channel.accept();
                            System.out.println("接收到连接请求:"
                                    + socketChannel.getRemoteAddress().toString());
                            socketChannel.configureBlocking(false);
                            //每接收请求,注册到同一个selector中处理
                            socketChannel.register(selector, SelectionKey.OP_READ);
                        } else if (selectionKey.isReadable()) {
                            System.out.println("接收到读信号,开线程进行读取... ...");
                            threadPoolExecutor.execute(new ReciveMessageTask(selectionKey,MessageQueue));
                        }
                    }
                }
            }
        } catch (IOException e) {
            System.out.println("Start  Server Fail");
        }
    }
复制代码
//接受消息线程
public
class ReciveMessageTask implements Runnable { private SocketChannel socketChannel; private LinkedBlockingQueue<byte[]> MessageQueue; ReciveMessageTask(SelectionKey selectionKey, LinkedBlockingQueue<byte[]> queue){ SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); this.socketChannel=socketChannel; this.MessageQueue=queue; } @Override public void run() { ByteBuffer buffer = ByteBuffer.allocate(1024); byte[] b; try { b=new byte[16]; int index=0; buffer.clear(); int cout=socketChannel.read(buffer); while(cout!=-1){ buffer.flip(); while (buffer.hasRemaining()){ byte getchar=buffer.get(); System.out.println(getchar); b[index]=getchar; index++; } buffer.clear(); cout=socketChannel.read(buffer); } System.out.println("put Message into Queue... ..."); MessageQueue.offer(b); } catch (Exception e) { try { e.printStackTrace(); //取消这个通道的注册,关闭资源 socketChannel.close(); } catch (IOException ex) { } } } }
复制代码

 

 




Rekent的主页 Rekent | 初学一级 | 园豆:91
提问于:2018-03-20 14:05
< >
分享
所有回答(1)
0

找到原因了吗 试试在调用完异步处理后sleep几秒钟

南风0001 | 园豆:202 (菜鸟二级) | 2019-11-28 20:01
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册