传统的BIO方式是基于流进行读写的,而且是阻塞的。要想处理并发请求,必须要产生新的线程来处理读写任务。为了提高IO性能,引入了NIO就是new IO的意思。
NIO的底层实现。NIO在C语言级别使用到了多路复用IO的技术 select、poll、epoll。
1,通道 通道( Channel ),到如何目的地( 或来自如何地方 ) 的所有数据都必须通过一个通道对象。
2,缓冲区 缓冲区实质上是一个容器对象。发送给通道的所有对象都必须先放到缓冲区中,同样从通道读取的如何数据要先读到缓冲区中。
3,选择器 NIO提供了选择器组件(Selector)用于同时检测多个通道的事件以实现异步I/O。我们将事件注册到Selector,当事件发生时可以通过Selector获取事件发生的通道。
package com.program.Server; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; public class NioServer { RequestProcessing processing=new RequestProcessing(); private Selector selector; public void init() throws IOException { this.selector=Selector.open(); //创建ServerSocketChannel ServerSocketChannel channel=ServerSocketChannel.open(); //设置非阻塞 channel.configureBlocking(false); ServerSocket serverSocket=channel.socket(); //绑定端口 InetSocketAddress address=new InetSocketAddress(8080); serverSocket.bind(address); channel.register(this.selector, SelectionKey.OP_ACCEPT);//注册监听事件 } public void start() throws IOException { while(true){ //此方法会阻塞,直到至少有一个已注册的事件发生 this.selector.select(); //获取发生事件集合对象 Iteratoriterator = this.selector.selectedKeys().iterator(); while (iterator.hasNext()){ SelectionKey key = (SelectionKey) iterator.next(); iterator.remove(); //如果为注册 if (key.isAcceptable()){ accept(key); }else if(key.isReadable()){ read(key); } } } } public void accept(SelectionKey key) throws IOException { ServerSocketChannel server= (ServerSocketChannel) key.channel(); //接收链接 SocketChannel accept = server.accept(); //设置为非阻塞 accept.configureBlocking(false); //创建读取缓冲区 accept.register(this.selector,SelectionKey.OP_READ); } public void read(SelectionKey key) throws IOException { SocketChannel channel =(SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); // 读取数据 int read = channel.read(buffer); if (read>0){ String request = new String(buffer.array()).trim(); System.out.println(request); // http响应消息 processing.GetReturn().getBytes() ByteBuffer outBuffer = ByteBuffer.wrap(processing.GetReturn().getBytes()); channel.write(outBuffer); }else{ System.out.println("客户端关闭"); key.cancel(); } } public static void main(String[] args) throws IOException { NioServer server=new NioServer(); server.init(); server.start(); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)