NIO客户端的实现上一篇文章我们提到了NIO,大家应该对NIO有了一定的了解,接下来我们继续学习NIO的客户端实现 1、代码展示首先我们还是先启动一个线程public class NioServer { public static void main(String [] args){ //启动一个线程 new Thread(new NioServerHandle()).start(); }
} 处理类public class NioServerHandle implements Runnable{private ServerSocketChannel serverSocketChannel; private Selector selector; boolean stop = false; //初始化注册 public NioServerHandle(){ try { //获取ServerSocketChannel对象 serverSocketChannel = ServerSocketChannel.open(); //绑定ip serverSocketChannel.socket().bind(new InetSocketAddress('127.0.0.1',8989)); //设置为非阻塞 serverSocketChannel.configureBlocking(false); //获取Selector selector = Selector.open(); //将管道注册到多路复用器selector上 serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT); } catch (IOException e) { e.printStackTrace(); System.exit(1); } } public void stop(){ this.stop = true; } @Override public void run() { //轮询key while (!stop){ try { //设置超时时间 selector.select(1000); //获取所有key Set selectionKeys = selector.selectedKeys(); //遍历 Iterator it = selectionKeys.iterator(); SelectionKey selectionKey = null; while (it.hasNext()){ selectionKey = it.next(); //获取到就绪数组进行操作,并移除 it.remove(); try { handle(selectionKey); }catch (Exception e){ selectionKey.cancel(); selectionKey.channel().close(); } } } catch (IOException e) { e.printStackTrace(); } } } /** * 处理 * @param key * @throws Exception */ public void handle(SelectionKey key) throws Exception{ if (key.isValid()){ if (key.isAcceptable()){ //获取ServerSocketChannel ServerSocketChannel ssc = (ServerSocketChannel)key.channel(); //接受请求 SocketChannel sc = ssc.accept(); //设置为非阻塞 sc.configureBlocking(false); //注册到多路复用器 sc.register(selector,SelectionKey.OP_READ); } //read data if (key.isReadable()){ //得到SocketChannel SocketChannel sc = (SocketChannel) key.channel(); //设置字节缓冲区 ByteBuffer readBuffer = ByteBuffer.allocate(1024); //将通道的数据读取码流 int readByte = sc.read(readBuffer); //对于大于0的情况进行编解码 if (readByte > 0){ //将当前的缓冲区的limit设置为0,让后面进行读取 readBuffer.flip(); //根据缓冲区的可读大小设置字节数组 byte [] bytes = new byte[readBuffer.remaining()]; //get将读取的数据放入字节数组 readBuffer.get(bytes); //将字节数组按照UTF-8的格式输出到body String body = new String(bytes,'UTF-8'); System.out.print('The Time server recevive order:'+body); String currentTime = 'query'.equals(body)?new java.util.Date(System.currentTimeMillis()).toString():'No'; //进行输出操作 doWrite(sc,currentTime); }else if (readByte < 0 ){ key.cancel(); sc.close(); }else { } } } } /** * 将数据返回给客户端 * @param sc * @param currentTime * @throws Exception */ public void doWrite(SocketChannel sc,String currentTime) throws Exception{ if (currentTime != null && currentTime.trim().length() > 0){ //转换为字节数组,放到缓冲区 byte [] bytes = currentTime.getBytes(); ByteBuffer byteBuffer = ByteBuffer.allocate(bytes.length); byteBuffer.put(bytes); byteBuffer.flip(); sc.write(byteBuffer); } }}
|