Java-NIO-Selector
来源:互联网 发布:java计算器程序 编辑:程序博客网 时间:2024/06/15 11:19
1.背景
在jdk1.4,nio引入到java中;
C/C++代码的工具箱中,许多年前就已经有 select()和 poll()这两个POSIX(可移植性操作系统接口)系统调用可供使用了。许过操作系统也提供相似的功能,但对Java 程序员来说,就绪选择功能直到 JDK 1.4 才成为可行的方案。
本文编写一个client-server小程序,都采用Selector来管理连接;
2.例子
2.1客户端
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;import java.net.InetSocketAddress;import java.net.SocketAddress;import java.nio.ByteBuffer;import java.nio.channels.ClosedChannelException;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Set;import java.util.concurrent.ArrayBlockingQueue;/** * Created by Administrator on 2017/8/10. */public class MyClient { private static Logger logger = LoggerFactory.getLogger(MyClient.class); private int buffsize = 512; private ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue(1); public void testClient(){ Selector selector = null; try { selector = Selector.open(); } catch (IOException e) { logger.error("",e); } SocketChannel socketChannel = null; try { socketChannel = SocketChannel.open(); socketChannel.configureBlocking(false); } catch (IOException e) { logger.error("",e); } SocketAddress socketAddress = new InetSocketAddress(4444); try { socketChannel.connect(socketAddress); } catch (IOException e) { logger.error("",e); } try { socketChannel.register(selector,SelectionKey.OP_CONNECT); } catch (ClosedChannelException e) { logger.error("",e); } //handle logger.info("start"); for (;;){ try { if(selector.select(3000) == 0 ){ logger.info("client continue select..."); continue; } } catch (IOException e) { logger.error("",e); } Set<SelectionKey> selectionKeySet = selector.selectedKeys(); Iterator iterator = selectionKeySet.iterator(); while (iterator.hasNext()){ SelectionKey selectionKey = (SelectionKey) iterator.next(); if(selectionKey.isValid() && selectionKey.isConnectable()){ socketChannel = (SocketChannel) selectionKey.channel(); try { socketChannel.configureBlocking(false); } catch (IOException e) { logger.error("",e); try { socketChannel.close(); } catch (IOException e1) { logger.error("",e); } } try { socketChannel.register(selector,SelectionKey.OP_READ | SelectionKey.OP_WRITE); } catch (ClosedChannelException e) { logger.error("",e); try { socketChannel.close(); } catch (IOException e1) { logger.error("",e); } } //(作为客户端有责任)发送第一个请求 try { if(socketChannel.finishConnect()){ ByteBuffer byteBuffer = ByteBuffer.wrap("first request".getBytes()); socketChannel = (SocketChannel) selectionKey.channel(); try { socketChannel.write(byteBuffer); } catch (IOException e) { logger.error("",e); socketChannel.close(); } } } catch (IOException e) { logger.error("",e); } } if(selectionKey.isValid() && selectionKey.isWritable()){ socketChannel = (SocketChannel) selectionKey.channel(); if(socketChannel.isConnected()){ ByteBuffer byteBuffer = ByteBuffer.wrap("i'm client".getBytes()); socketChannel = (SocketChannel) selectionKey.channel(); try { socketChannel.write(byteBuffer); } catch (IOException e) { logger.error("",e); try { socketChannel.close(); } catch (IOException e1) { logger.error("",e); } } } } if(selectionKey.isValid() && selectionKey.isReadable()){ socketChannel = (SocketChannel) selectionKey.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); try { socketChannel.read(byteBuffer); } catch (IOException e) { logger.error("",e); try { socketChannel.close(); } catch (IOException e1) { logger.error("",e); } } logger.info("" + new String(byteBuffer.array())); String msg = new String(byteBuffer.array()); //进行粘包处理 String[] arr = msg.split(";"); String _msg = null; for (int i=0;i < arr.length;i++){ logger.info("进行粘包处理后:" + new String(arr[i])); //假设知道内容大小 int size = 10;//假设知道size=10 if(arr[i].length() < size){ logger.info("这个信息拆包了,拆包后的内容:"+arr[i]); if(blockingQueue.size()!=0){ try { _msg = blockingQueue.take() + arr[i]; logger.info("这个信息拆包了,拆包处理后的内容:"+_msg); } catch (InterruptedException e) { logger.error("",e); } }else{ blockingQueue.offer(arr[i]); } } } } iterator.remove(); } } }}
2.2 服务端
import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;import java.net.InetSocketAddress;import java.net.SocketAddress;import java.net.SocketException;import java.nio.ByteBuffer;import java.nio.channels.*;import java.util.Iterator;import java.util.Set;/** * Created by Administrator on 2017/8/10. */public class MyServer { private static Logger logger = LoggerFactory.getLogger(MyServer.class); private int buffsize = 512; public void testServer(){ Selector selector = null; try { selector = Selector.open(); } catch (IOException e) { logger.error("Selector.open() occur Excetion!",e); } ServerSocketChannel serverSocketChannel = null; try { serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); SocketAddress socketAddress = new InetSocketAddress(4444); serverSocketChannel.bind(socketAddress); } catch (IOException e) { logger.error("",e); } int ops = serverSocketChannel.validOps(); try { serverSocketChannel.register(selector, ops); } catch (ClosedChannelException e) { logger.error("",e); } //handle logger.info("start"); for (;;){ try { if(selector.select(3000) == 0 ){ logger.info("server continue select..."); continue; } } catch (IOException e) { logger.error("",e); } Set<SelectionKey> selectionKeySet = selector.selectedKeys(); Iterator iterator = selectionKeySet.iterator(); while (iterator.hasNext()){ SelectionKey selectionKey = (SelectionKey) iterator.next(); if(selectionKey.isValid() && selectionKey.isAcceptable()){ serverSocketChannel = (ServerSocketChannel) selectionKey.channel(); SocketChannel socketChannel = null; try { socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); int _ops = socketChannel.validOps(); socketChannel.register(selector,_ops); } catch (IOException e) { logger.error("",e); try { socketChannel.close(); } catch (IOException e1) { logger.error("",e); } } } if(selectionKey.isValid() && selectionKey.isReadable()){ SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(10);//1024byte try { socketChannel.read(byteBuffer); } catch (IOException e) { logger.error("",e); try { socketChannel.close(); } catch (IOException e1) { logger.error("",e); } } logger.info("" + new String(byteBuffer.array())); } if(selectionKey.isValid() && selectionKey.isWritable()){ SocketChannel socketChannel = (SocketChannel) selectionKey.channel(); try { socketChannel.socket().setTcpNoDelay(true); } catch (SocketException e) { logger.error(""); } ByteBuffer byteBuffer = ByteBuffer.wrap("i'm server;".getBytes()); try { socketChannel.write(byteBuffer); } catch (IOException e) { logger.error("",e); try { socketChannel.close(); } catch (IOException e1) { logger.error("",e); } }// byteBuffer.flip(); } iterator.remove(); } } }}
2.3 启动测试
public class MyClinetTest { @Test public void testClient(){ MyClient myClient = new MyClient(); myClient.testClient(); }}
public class MyServerTest { @Test public void testServer(){ MyServer myServer = new MyServer(); myServer.testServer(); }}
阅读全文
1 0
- Java NIO Selector
- JAVA NIO之selector
- Java NIO(7-Selector)
- Java NIO Selector
- Java NIO Selector
- java NIO- Selector
- Java nio selector
- Java NIO Selector
- Java NIO--Selector
- Java NIO (六) Selector
- Java NIO Selector
- Java NIO(3)----Selector
- Java NIO之Selector
- Java NIO Selector
- Java NIO Selector
- Java NIO之Selector
- Java NIO 之selector
- java NIO Selector详解
- spring aop详解
- soapUI依据上一步骤的出参实现分情景跳转
- 指针的理解
- vue.js中的多组件过渡实例
- 23.driverbase-易错点:CreateFile返回1
- Java-NIO-Selector
- C++中vector的用法
- 289 苹果(01背包)
- Oracle insert all语句介绍
- JMeter-线程组
- Android HandlerThread
- 【Android笔记-4】ListView Android:divider
- Spring事务管理详解
- sc2017新初三膜你赛8 比赛总结