当前位置: 首页 > 后端技术 > Java

JavaNioExample

时间:2023-04-02 00:35:35 Java

selector模型使用一个线程来监听多个IO请求。如果有任何IO数据准备就绪,则通知相应的线程处理选择模型。它的基本原理是使用轮询和遍历。也就是说,客户端在操作服务器时,会创建三个文件描述符,简称FD。分别是writefds(写描述符)、readfds(读描述符)和exceptfds(异常描述符)demo,让主线程监听IO事件然后处理serverpublicclassNioServerExample{publicstaticvoidmain(String[]args)throwsIOException,InterruptedException{选择器选择器=getSelector();听(选择器);}publicstaticSelectorgetSelector()throwsIOException{Selectorselector=Selector.open();//创建一个可选通道并设置一个非阻塞的ServerSocketChannelserverSocketChannel=ServerSocketChannel.open);serverSocketChannel.configureBlocking(false);//绑定通道到指定端口ServerSocketsocket=serverSocketChannel.socket();socket.bind(新InetSocketAddress(8080));//向selector注册IO事件,先注册SelectionKey.OP_ACCEPT让serveraccept监听serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);返回选择器;}publicstaticvoidlisten(Selectorselector)throwsIOException,InterruptedException{while(selector.select()>0){设置selectionKeys=selector.selectedKeys();Iteratoriterator=selectionKeys.iterator();if(iterator.hasNext()){SelectionKeykey=iterator.next();//判断IO事件类型进行处理process(selector,key);迭代器.remove();}}}privatestaticvoidprocess(Selectorselector,SelectionKeykey)throwsIOException,InterruptedException{if(key.isAcceptable()){System.out.println(Thread.currentThread().getName()+"=>事件类接受");ServerSocketChannelserver=(ServerSocketChannel)key.channel();SocketChannel通道=server.accept();channel.configureBlocking(false);channel.register(selector,SelectionKey.OP_READ);}elseif(key.isReadable()){System.out.println(Thread.currentThread().getName()+"=>事件类型read&qu哦;);SocketChannel通道=(SocketChannel)key.channel();ByteBufferbyteBuffer=ByteBuffer.allocate(500);intlen=channel.read(byteBuffer);if(len>0){字符串内容=newString(byteBuffer.array(),0,len);System.out.println(内容);channel.register(选择器,SelectionKey.OP_WRITE);}byteBuffer.clear();}elseif(key.isWritable()){System.out.println(Thread.currentThread().getName()+"=>事件类类型write");SocketChannel通道=(SocketChannel)key.channel();Stringstr="clientfuckyou我是NioServer";channel.write(ByteBuffer.wrap(str.getBytes()));channel.register(selector,SelectionKey.OP_READ);//channel.close();//向客户端发送数据后管此通道连接}}}clientpublicclassNioClientExample0{publicstaticvoidmain(String[]args)抛出IOException,InterruptedException{Selectorselector=Selector.open();SocketChannelsocketChannel=SocketChannel.open();socketChannel.setOption(StandardSocketOptions.TCP_NODELAY,true);socketChannel.connect(newInetSocketAddress("127.0.0.1",8080));socketChannel.configureBlocking(false);socketChannel.register(选择器,SelectionKey.OP_WRITE);字符串信息=空;扫描仪扫描仪=新扫描仪(System.in);ByteBufferbyteBuffer0=ByteBuffer.allocate(100);ByteBufferbyteBuffer1=ByteBuffer.allocate(100);while(true){intlen=socketChannel.read(byteBuffer1);System.out.println(newString(byteBuffer1.array(),0,len));byteBuffer1.clear();信息=扫描仪.next();byteBuffer0.put(info.getBytes());byteBuffer0.flip();socketChannel.write(byteBuffer0);字节Buffer0.clear();}}}参考示例如下,启动服务端和一个客户端后,使用客户端向服务端发送一段数据,当服务端收到数据并写回客户端时,注册为读事件,准备接收数据然后打开一个client,你会发现server并没有一直在等待IO读取事件,而是转身去processaccept接收新的连接

猜你喜欢