使用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多路复用的优势并不是对单个连接处理得更快,而是在于它能处理更多的连接。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值