nio demo

来源:互联网 发布:人工智能疾病诊断 编辑:程序博客网 时间:2024/06/05 03:47

写了nio的demo


package com.io;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.ServerSocketChannel;import java.nio.channels.SocketChannel;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Iterator;import java.util.Set;/** * mainReactor模型 * mainReactor进行接收,然后dispatch给subReactor,由subReactor去定义selector,注册read事件 * subReactor再dispatcher给executor *  * 针对nio中的异步,并不是操作系统说的内核准备数据,拷贝到用户进程缓存这个过程。 * 而是用户线程没有得到数据,还可以继续往下执行。直到selector线程通过 *  * io请求通用过程 read--decode--compute--encode--send *  * @author Administrator *  *  * */public class NIOServer {public static void main(String[] args) {createServer();}public static void createServer() {TimeServer timeServer = new TimeServer();timeServer.start();}static class TimeServer extends Thread {// serverprivate ServerSocketChannel serverSocketChannel;// 多路复用器,将channel注册到多路复用器,selector会不断的轮询注册在其上的channel,// 一旦某个channel上有读写事件,表示channel已经就绪,通过selectionKey可以获取就绪的channel集合//private Selector selector;public TimeServer() {try {selector = Selector.open();serverSocketChannel = ServerSocketChannel.open();// 配置是否阻塞serverSocketChannel.configureBlocking(false);// 绑定ip端口serverSocketChannel.socket().bind(new InetSocketAddress("127.0.0.1", 8888));// 注册accept到selectorserverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {try {// 这是个死循环,不断的轮询,没有阻塞while (true) {selector.select(1000);Set<SelectionKey> selectedKeys = selector.selectedKeys();Iterator<SelectionKey> iterator = selectedKeys.iterator();while (iterator.hasNext()) {SelectionKey selectionKey = iterator.next();// 移除已经就绪的selectionKeyiterator.remove();handle(selectionKey);}// 清除已经轮询到的就绪的channel,或者在迭代器里面remove// selectedKeys.clear();}} catch (Exception e) {e.printStackTrace();} finally {if (selector != null) {try {selector.close();} catch (IOException e) {e.printStackTrace();}}}}private void handle(SelectionKey selectionKey) throws IOException {if (selectionKey.isValid()) {if (selectionKey.isAcceptable()) {// 接收新请求ServerSocketChannel ssc = (ServerSocketChannel) selectionKey.channel();SocketChannel sc = ssc.accept();sc.configureBlocking(false);// sc.register(selector, SelectionKey.OP_ACCEPT);sc.register(selector, SelectionKey.OP_READ);}if (selectionKey.isReadable()) {SocketChannel sc = (SocketChannel) selectionKey.channel();ByteBuffer readBuffer = ByteBuffer.allocate(1024);// channel操作buffer,channel.readint readBytes = sc.read(readBuffer);if (readBytes > 0) {readBuffer.flip();byte[] bytes = new byte[readBuffer.remaining()];readBuffer.get(bytes);String body = new String(bytes, "utf-8");System.out.println("The time server receive order:" + body);if ("get time".equals(body)) {String time = getNowDate();writeTime(sc, time);}} else if (readBytes < 0) {selectionKey.cancel();sc.close();} else {// 读到0字节,忽略}}}}/** * channel操作buffer,channel.write *  * @param sc * @param time * @throws IOException */private void writeTime(SocketChannel sc, String time) throws IOException {if (time != null && time.trim().length() > 0) {byte[] bytes = time.getBytes();ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);writeBuffer.put(bytes);writeBuffer.flip();sc.write(writeBuffer);}}public static String getNowDate() {Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss.S");return sdf.format(date);}}}
package com.io;import java.io.IOException;import java.net.InetSocketAddress;import java.nio.ByteBuffer;import java.nio.channels.SelectionKey;import java.nio.channels.Selector;import java.nio.channels.SocketChannel;import java.util.Iterator;import java.util.Set;public class NIOClient {public static void main(String[] args) {TimeClient timeClient = new TimeClient();timeClient.start();}static class TimeClient extends Thread {private SocketChannel socketChannel;private Selector selector;public TimeClient() {try {selector = Selector.open();socketChannel = SocketChannel.open();socketChannel.configureBlocking(false);} catch (IOException e) {e.printStackTrace();}}@Overridepublic void run() {try {doConnect();} catch (IOException e) {e.printStackTrace();}while (true) {try {selector.select(1000);Set<SelectionKey> set = selector.selectedKeys();Iterator<SelectionKey> iterator = set.iterator();while (iterator.hasNext()) {SelectionKey selectionKey = iterator.next();iterator.remove();try {handle(selectionKey);} catch (Exception e) {if (selectionKey != null) {selectionKey.cancel();if (selectionKey.channel() != null) {selectionKey.channel().close();}}e.printStackTrace();}}} catch (IOException e) {e.printStackTrace();}}}private void handle(SelectionKey selectionKey) throws IOException {if (selectionKey.isValid()) {SocketChannel socketChannel = (SocketChannel) selectionKey.channel();if (selectionKey.isConnectable()) {if (socketChannel.finishConnect()) {socketChannel.register(selector, SelectionKey.OP_READ);writeTime(socketChannel, "get time");}}if (selectionKey.isReadable()) {ByteBuffer readBuffer = ByteBuffer.allocate(1024);int readBytes = socketChannel.read(readBuffer);if (readBytes > 0) {readBuffer.flip();byte[] bytes = new byte[readBuffer.remaining()];readBuffer.get(bytes);String body = new String(bytes, "UTF-8");System.out.println("time is " + body);} else if (readBytes < 0) {selectionKey.cancel();socketChannel.close();} else {}}}}private void doConnect() throws IOException {// 连接到服务端boolean isConnected = socketChannel.connect(new InetSocketAddress("127.0.0.1", 8888));if (isConnected) {// 连接成功,注册read事件到selectorsocketChannel.register(selector, SelectionKey.OP_READ);writeTime(socketChannel, "get time");} else {socketChannel.register(selector, SelectionKey.OP_CONNECT);}}/** * channel操作buffer,channel.write *  * @param sc * @param time * @throws IOException */private void writeTime(SocketChannel sc, String time) throws IOException {if (time != null && time.trim().length() > 0) {byte[] bytes = time.getBytes();ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);writeBuffer.put(bytes);writeBuffer.flip();sc.write(writeBuffer);}}}}



0 0
原创粉丝点击