• 使用Socket实现HttpServer(三)


    使用Socket实现HttpServer(三)

    这一章继续对我们的服务器进行优化,引入 NIO

    package com.fengsir.network.step4;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.nio.ByteBuffer;
    import java.nio.channels.*;
    import java.nio.charset.StandardCharsets;
    import java.util.Iterator;
    import java.util.Set;
    
    /**
     * @Author FengZeng
     * @Date 2022-01-24 15:49
     * @Description TODO
     */
    public class Step4Server {
    
      ServerSocketChannel ssc;
    
      public void listen(int port) throws IOException {
        ssc = ServerSocketChannel.open();
        ssc.bind(new InetSocketAddress(port));
    
        // No blocking...
        ssc.configureBlocking(false);
    
        Selector selector = Selector.open();
    
        ssc.register(selector, ssc.validOps());
    
        ByteBuffer buffer = ByteBuffer.allocate(1024 * 16);
    
        for (; ; ) {
    
          // numOfSelector == selectedKeys.size(),必须执行 selector.select()
          int numOfSelector = selector.select();
          Set<SelectionKey> selectedKeys = selector.selectedKeys();
    
          // 轮训当前所有的事件
          for (SelectionKey key : selectedKeys) {
    
            // 如果事件已就绪
            if (key.isAcceptable()) {
    
              SocketChannel channel = ssc.accept();
              if (channel == null) {
                continue;
              }
    
              // Kernel -> mmap(buffer) -> channel -> user(buffer)
              channel.configureBlocking(false);
              // 将事件注册为读就绪
              channel.register(selector, SelectionKey.OP_READ);
    
              // 读事件已就绪
            } else if (key.isReadable()){
    
              SocketChannel channel = (SocketChannel) key.channel();
              
              // _ _ _ _ _ _ _
              //         P(position)
              buffer.clear();
              channel.read(buffer);
    
              String request = new String(buffer.array());
              System.out.println(request);
    
              buffer.clear();
              buffer.put("HTTP/1.1 200 ok\n\nHello NIO!".getBytes(StandardCharsets.UTF_8));
              // HTTP/1.1 200 OK ... ! _ _ _
              //                       P
              // P
              buffer.flip();
              channel.write(buffer);
              channel.close();
            }
          }
        }
    
      }
    
      public static void main(String[] args) throws IOException {
        Step4Server step4Server = new Step4Server();
        step4Server.listen(8000);
    
      }
    }
    
    

    NIO 翻译成 New IO ,是 JDK1.4 引入的一种新的 IO模型,传统的 IO 只能是阻塞的模型,而 NIO 可以实现非阻塞,也就是代码中的 ssc.configureBlocking(false);这一句,在前面实现的 Http Server 里面,当我们去调用 accept() 的时候,如果没有请求进来,线程是阻塞在这里的。

    引入 NIO 最大的亮点就是:IO多路复用IO多路复用的优势并不是对单个连接处理得更快,而是在于它能处理更多的连接。

  • 相关阅读:
    CentOS6 配置阿里云 NTP 服务
    使用docker-compose运行nginx容器挂载时遇到的文件/目录问题
    Springboot配置文件参数使用docker-compose实现动态配置
    Dockerfile文件全面详解
    docker 生成mysql镜像启动时自动执行sql
    CentOS无法识别NTFS格式U盘完美解决方案
    网络模型与网络策略
    k8s更换网络插件:从flannel更换成calico
    数据采集实战(四)-- 线性代数习题答案下载
    leedcode 146. LRU 缓存机制(哈希+双向链表)
  • 原文地址:https://www.cnblogs.com/Fzeng/p/15840084.html
Copyright © 2020-2023  润新知