Skip to content

网络编程基础

同步非阻塞 I/O (NIO)

  1. 使用Channel代替Stream
  2. 使用Selector代替Channel
  3. 可以在一个线程里处理多个Channel

Buffer结构

  1. position指针: 写入位置。limit: 限制位置。capacity: 理论长度。
  2. 写模式: 从position位置开始写入数据, limit指针则到capacity的位置。
  3. flip()方法: 将buffer对象从写模式进行反转, 过程为将position指针调回原本的位置, 将limit指针调整到position指针的位置。
  4. 读数据: 首先调用flip()方法, 然后就进入了读模式。
    1. position指针移动到limit指针, 将全部数据读入。调用clear()方法将position指针移动到初始位置, limit指针移动到capacity位置。相当于调整回写模式。
    2. position指针向limit指针移动, 但是未完全读取完毕。调用compact()方法, 将剩余的内容拷贝到栈的开头, 类似于覆盖的方式使剩余内容可以在下一轮用同样方式调取。

Channel操作

  1. FileChannel

    1. NoBufferStreamCopy
    java
    private static void close(Closeable closeable) {
      if (closeable != null) {
        try {
          closeable.close();
        } catch (IOException e) {
          e.printStackTrace();
        }
      }
    }
    
    public void copyFile(File source, File target) {
      InputStream fin = null;
      OutputStream fout = null;
      try {
        fin = new FileInputStream(source);
        fout = new FileOutputStream(target);
        
        int result;
        while ((result = fin.read()) != -1) {
          fout.write(result);
        }
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOexception e) {
        e.printStackTrace();
      } finally {
        close(fin);
        close(fout);
      }
    }
    1. BufferedStreamCopy
    java
    public void copyFile(File source, File target) {
      InputStream fin = null;
      OutputStream fout = null;
      
      try {
        fin = new BufferedInputStream(new FileInputStream(source));
        fout =new BufferedOutputStream(new FileOutputStream(target));
        
        byte[] buffer = new byte[1024];
        
        int result;
        while ((reuslt = fin.read(buffer)) != -1) {
          fout.write(buffer, 0, result);
        }
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOexception e) {
        e.printStackTrace();
      } finally {
        close(fin);
        close(fout);
      }
    }
    1. NioBufferCopy
    java
    public void copyFile(File source, File target) {
      FileChannel fin = null;
      FileChannel fout = null;
      
      try {
        fin = new FileInputStream(source).getChannel();
        fout = new FileOutputStream(target).getChannel();
        
        ByteBuffer buffer = ByteBuffer.allocate(1024); // 给与容量
        while (fin.read(buffer) != -1) {
          buffer.flip();
          while (buffer.hasRemaining()) {
            fout.write(buffer);
          }
          buffer.clear();
        }
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOexception e) {
        e.printStackTrace();
      } finally {
        close(fin);
        close(fout);
      }
    }
    1. NioTransferCopy
    java
    public void copyFile(File source, File target) {
      FileChannel fin = null;
      FileChannel fout = null;
      
      try {
        fin = new FileInputStream(source).getChannel();
        fout = new FileOutputStream(target).getChannel();
        long transferred = 0L;
        long size = fin.size();
        while (transferred != size) {
          transferred += fin.transferTo(0, size, fout); // position, byte size, out channel
        }
      } catch (FileNotFoundException e) {
        e.printStackTrace();
      } catch (IOexception e) {
        e.printStackTrace();
      } finally {
        close(fin);
        close(fout);
      }
    }
  2. ServerSocketChannel

  3. SocketChannel

Selector

  • 注册过程: Channel -> Selector -> SelectionKey
    1. interestOps(): (对于这个SelectionKey)检测该Channel是否为可读状态
    2. readyOps(): 检测Channel处于哪些可操作状态下
    3. channel(): 返回该key对应的channel
    4. selector(): 检测有多少Channel处于Selector监听的可操作状态上。
    5. attachment(): 将一个对象或者更多的信息附着到SelectionKey上

异步 I/O (AIO)

Async(Server)SocketChannel操作

方法

  1. connect/accept -> implements CompletionHandler<AsynchronousSocketChannel, Object>(回调函数)
  2. read -> buffer, attachment, handler
  3. write

Future

CompletionHandler

Tomcat结构

  1. Server -> (一对多)Service -> (一对多)Connector -> Processor -> Engine
  2. Server使Tomcat服务器最顶层组件, 负责加载服务器资源和环境变量
  3. Service集合Connector和Engine的抽象组件, 一个Service可以包含多个Connector和一个Engine
  4. Connector提供基于不同特定协议的实现, 接受解析请求, 返回响应
  5. 经Processor派遣请求至Engine进行处理
  6. Engine是容器的顶层组件, 容器使Tomcat用来处理请求的组件, 容器内部的组件按照层级排列
  7. Host代表一个虚拟主机, 一个Engine可以支持对多个虚拟主机的请求, Engine通过解析请求来决定将请求发送给哪一个Host
  8. Context代表一个Web Application, 应用资源管理, 应用类加载, Servlet管理, 安全管理等
  9. Wrapper是容器最底层的组件, 用于包裹住Servlet实例, 负责管理Servlet实例的生命周期