让每一名学员高薪就业
返回列表 发新帖

利用NIO模拟实现Tomcat容器

[复制链接]

135

主题

289

帖子

2658

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2658

版主

发表于 2019-8-15 17:41:07  | 显示全部楼层 | 阅读模式
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

主题

9

帖子

15

积分

菜鸟

Rank: 1

积分
15
发表于 2019-8-15 17:46:29  | 显示全部楼层
翻了几百页源码社区贴,经常看到你  
回复 支持 反对

使用道具 举报

0

主题

8

帖子

4

积分

菜鸟

Rank: 1

积分
4
发表于 2019-8-15 17:47:23  | 显示全部楼层
好东西一定要看看!
回复 支持 反对

使用道具 举报

0

主题

7

帖子

7

积分

菜鸟

Rank: 1

积分
7
发表于 2019-8-15 17:50:20  | 显示全部楼层
后悔当初我没有培训
回复 支持 反对

使用道具 举报

0

主题

7

帖子

7

积分

菜鸟

Rank: 1

积分
7
发表于 2019-8-15 17:50:40  | 显示全部楼层
我要把这个帖子一直往上顶!
回复 支持 反对

使用道具 举报

0

主题

7

帖子

6

积分

菜鸟

Rank: 1

积分
6
发表于 2019-8-15 17:56:15  | 显示全部楼层
源码的老师最棒!
回复 支持 反对

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

最新活动

联系我们

Java培训  |   PHP培训  |   UI培训  |   H5培训  |   Python培训  |   大数据培训  |   如何报名  |   视频下载
快速回复 返回顶部 返回列表