源码时代JAVA干货分享 | 利用NIO模拟实现Tomcat容器!

NIO是什么

New IO,始于Java1.4,提供新的非阻塞 JavaIO 操作API.

又称Non-Blocking IO 非阻塞IO

替代旧版本的Blocking IO, 多用于网络相关的API.

 

为什么要使用NIO

使用NIO后,WEB网络程序性能可以进一步提高

 

     

模拟Tomcat7, 阻塞IO处理Http请求:

 

public class BIOHttpServer {

public static void main(String[] args) throws IOException {

ServerSocket socket = new ServerSocket(8080);

System.out.println(Thread.currentThread().getName()+"启动:"+8080);

while(true){

Socket accept = socket.accept();

InputStream inputStream = accept.getInputStream();

byte[] b = new byte[1024];

inputStream.read(b);

System.out.println(new String(b));

 

// http响应头 必须这样写:

String response = "HTTP/1.1 200 ok\r\nContent-Length: 11\r\n\r\nHello World\r\n";

accept.getOutputStream().write(response.getBytes());

accept.getOutputStream().flush();

accept.close();

}

}

}

 

 

NIO高性能的核心原理:

发起连接

操作系统接收连接

TCP模块 + 多路复用机制

一个Java线程通过Selector工具选择性处理

有数据传输的交给线程池

最终达到,线程最大程度利用

 

 

使用NIO:

 

模拟Tomcat8.5, NIO处理Http请求:

public class NIOHttpServer {

public static void main(String[] args) throws IOException {

 

// 1.ServerSocketChannel 绑定端口

ServerSocketChannel socket = ServerSocketChannel.open();

socket.configureBlocking(false); // no-Blocking

socket.bind(new InetSocketAddress(8080));

 

System.out.println("NIO服务器启动,端口:"+8080);

 

// 2.获取新连接

// selector 获取不同操作系统下不同的tcp连接动态

Selector selector = Selector.open();

 

// 选择器,根据条件查询符合情况地TCP连接

socket.register(selector, SelectionKey.OP_ACCEPT);

 

while(true){

selector.select(1000); //如果没有新连接,就等待

 

// 3. 处理查询结果

Set<SelectionKey> keys = selector.selectedKeys();

Iterator<SelectionKey> iterator = keys.iterator();

 

while(iterator.hasNext()){

SelectionKey result = iterator.next();

 

//根据不同的类型,分别进行处理

if(result.isAcceptable()){ //3.1 拿到新连接对象

// nio体现,accept 不阻塞,没有连接则返回null

SocketChannel accept = socket.accept();

if(accept!=null){

// 注册连接对象,进行关注

accept.configureBlocking(false);// no-Blocking

accept.register(selector, SelectionKey.OP_READ);

}

}

if(result.isReadable()){ //3.2 有数据请求的连接

SocketChannel channel = (SocketChannel) result.channel();

// 处理过程中,先取消selector对应连接的注册,避免重复

result.cancel();

 

// NIO的读写方式: 字节缓冲区

ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

channel.read(byteBuffer);

byteBuffer.flip(); //模式转换

byte[] b = byteBuffer.array();

String request = new String(b);

 

//处理请求...

System.out.println(request);

 

//数据响应:NIO的写数据

String response = "HTTP/1.1 200 ok\r\nContent-Length: 11\r\n\r\nHello World\r\n";

channel.write(ByteBuffer.wrap(response.getBytes()));

 

// 处理完成,重新注册,继续接收处理新的连接

// channel.register(selector, SelectionKey.OP_READ);

}

// 删除处理过的结果(事件)

iterator.remove();

}

 

// 检查过程就绪,清除之前的调用效果

selector.selectNow();

}

}

}

 

(本文章由源码时代技术老师原创,转载请注明出处!)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值