为了账号安全,请及时绑定邮箱和手机立即绑定

nio使用线程处理每一个读写请求的写法问题

nio使用线程处理每一个读写请求的写法问题

ABOUTYOU 2019-01-17 19:19:46
问题描述 在写java nio的demo时,希望按照React的模式实现,对每一个已经就绪的请求,都在一个新的线程里处理。具体的代码如下面所示。 当一个客户端写完数据之后,断开连接时,会报错: java.nio.channels.ClosedChannelException 显然这种写法是不合适或者不对的。看到网上用的是 attach() 方法 selectionKey.attach(new Acceptor(selector,selectionKey)); 那么:问题1: 我采用的写法,是哪里导致客户端关闭时报错,错误原因是什么?问题2: attach()怎么用,为什么这种写法可以避免关闭客户端报错的情况? 相关代码 使用单独线程,进行select操作。 new Thread(() -> { try { while (selector.select() > 0) { for (SelectionKey selectionKey : selector.selectedKeys()) { try { selector.selectedKeys().remove(selectionKey); if (selectionKey.isAcceptable()) { SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); } if (selectionKey.isReadable()) { doRead(selectionKey); } } catch (IOException e) { selectionKey.cancel(); } } } } catch (IOException e) { e.printStackTrace(); } }).start(); 当遇到可读事件时,在一个新的线程里进行处理。 public void doRead(SelectionKey selectionKey) { new Thread(() -> { try { SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); String content = ""; int c = 0; while ((c = socketChannel.read(byteBuffer)) > 0) { byteBuffer.flip(); content += charset.decode(byteBuffer); } System.out.println(content); selectionKey.interestOps(SelectionKey.OP_READ); if (c == -1) { selectionKey.cancel(); socketChannel.close(); } } catch (IOException e) { e.printStackTrace(); } }).start(); }
查看完整描述

1 回答

  • 1 回答
  • 0 关注
  • 541 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信