标签:main com 私有 nts 转化 art ddr let 通道数
BIO:同步阻塞式IO
NIO:同步非阻塞式IO
AIO(NIO2.0):异步非阻塞式IO
同步:指虚拟机来完成IO读写,如果读写没有完成程序一直等待。
异步:指将读写交给操作系统来做,java代码要干的事就是将想读的写的东西给操作系统然后返回状态值,最后让操作系统通知程序是否完成。
阻塞:指对网络通信,一个客户端对应一个服务器线程,当链接数量多的时候,就会发生阻塞,其余的客户端连不上服务器。
非阻塞:将所谓的一个链接对应一个线程转化为一个请求对应一个线程,这里引入了通道和多路复用技术,由多路复用器来轮询通道是否请求读写,然后创建一个线程来处理他。
异步一般与操作系统关系比较密切,不同的操作系统异步的效率也是不一样的。
阻塞是可以用代码方式体现的:
1.创建服务器类,创建私有多路复用器,和buffer缓冲区对象。
2.创建服务器类的构造方法,通道绑定地址并且绑定通道设置监听。
3.创建客户端类,绑定通道,并用buffer输入通道。
1 package com.fan; 2 3 import java.io.IOException; 4 import java.net.InetSocketAddress; 5 import java.nio.ByteBuffer; 6 import java.nio.channels.SelectionKey; 7 import java.nio.channels.Selector; 8 import java.nio.channels.ServerSocketChannel; 9 import java.nio.channels.SocketChannel; 10 import java.util.Iterator; 11 12 public class Server implements Runnable { 13 14 private Selector selector;//创建多路复用器。 15 16 private ByteBuffer byteBuffer = ByteBuffer.allocate(1024);//创建ByteBuffer,并分配长度。 17 18 public Server(int port) {//创建构造函数。 19 try { 20 21 this.selector = Selector.open();//打开多路复用器。 22 23 ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();//打开服务器通道channel。 24 25 serverSocketChannel.configureBlocking(false);//设置该多通道为非阻塞的。 26 27 serverSocketChannel.bind(new InetSocketAddress(port));//给通道绑定服务器地址。 28 29 serverSocketChannel.register(this.selector, SelectionKey.OP_ACCEPT);//通道注册到多路复用器中,并设置监听事件。 30 31 System.out.println("Server start, port :" + port); 32 33 } catch (Exception e) { 34 35 } 36 } 37 38 @Override 39 public void run() { 40 while (true) { 41 try { 42 this.selector.select();//让多路复用器进行监听。 43 44 Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator();//返回多路选择器已经选择的集。 45 46 while (iterator.hasNext()) {//进行遍历。 47 48 SelectionKey selectionKey = iterator.next();//获取一个选择的元素。 49 50 iterator.remove();//将容器移除。 51 52 if (selectionKey.isValid()) { 53 if (selectionKey.isAcceptable()) { 54 this.accept(selectionKey); 55 } 56 if (selectionKey.isReadable()) { 57 this.read(selectionKey); 58 } 59 if (selectionKey.isWritable()) { 60 //this.write(selectionKey); //ssc 61 } 62 } 63 } 64 65 } catch (Exception e) { 66 67 } 68 } 69 } 70 71 private void write(SelectionKey key) { 72 //ServerSocketChannel ssc = (ServerSocketChannel) key.channel(); 73 //ssc.register(this.seletor, SelectionKey.OP_WRITE); 74 } 75 76 private void read(SelectionKey key) { 77 try { 78 this.byteBuffer.clear();//清空缓冲区旧的数据 79 80 SocketChannel socketChannel = (SocketChannel) key.channel();//获取之前注册的socket通道对象 81 82 int read = socketChannel.read(this.byteBuffer);//将通道数据读到buffer中 83 84 if(read==-1){//如果没数据就返回 85 key.channel().close(); 86 key.cancel(); 87 return; 88 } 89 90 this.byteBuffer.flip();//有数据则进行读取 读取之前需要进行复位方法(把position 和limit进行复位) 91 92 byte[] bytes = new byte[this.byteBuffer.remaining()];//根据缓冲区的数据长度创建相应大小的byte数组,接收缓冲区的数据 93 94 this.byteBuffer.get(bytes);// 接收缓冲区数据 95 96 String body = new String(bytes).trim(); 97 98 System.out.println("Server : " + body); 99 100 }catch (Exception e){ 101 102 } 103 } 104 private void accept(SelectionKey key) { 105 106 try { 107 ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel(); 108 SocketChannel accept = serverSocketChannel.accept(); 109 accept.configureBlocking(false); 110 accept.register(this.selector, SelectionKey.OP_READ); 111 }catch (Exception e){ 112 113 } 114 } 115 116 public static void main(String[] args) { 117 118 new Thread(new Server(8765)).start(); 119 120 } 121 122 }
1 package com.fan; 2 3 import java.io.IOException; 4 import java.net.InetSocketAddress; 5 import java.nio.ByteBuffer; 6 import java.nio.channels.SocketChannel; 7 8 public class Client { 9 10 11 public static void main(String[] args) { 12 InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8765); 13 14 SocketChannel sc = null; 15 16 ByteBuffer buf = ByteBuffer.allocate(1024); 17 18 try { 19 20 sc = SocketChannel.open(); 21 22 sc.connect(address); 23 24 while (true) { 25 26 byte[] bytes = new byte[1024]; 27 28 System.in.read(bytes); 29 30 buf.put(bytes); 31 32 buf.flip(); 33 34 sc.write(buf); 35 36 buf.clear(); 37 38 } 39 40 } catch (IOException e) { 41 42 e.printStackTrace(); 43 44 } finally { 45 46 if (sc != null) { 47 48 try { 49 50 sc.close(); 51 52 } catch (IOException e) { 53 54 e.printStackTrace(); 55 56 } 57 58 } 59 60 } 61 62 } 63 64 }
标签:main com 私有 nts 转化 art ddr let 通道数
原文地址:https://www.cnblogs.com/fan123yh/p/11262855.html