Appearance
网络编程基础
同步非阻塞 I/O (NIO)
- 使用Channel代替Stream
- 使用Selector代替Channel
- 可以在一个线程里处理多个Channel
Buffer结构
- position指针: 写入位置。limit: 限制位置。capacity: 理论长度。
- 写模式: 从position位置开始写入数据, limit指针则到capacity的位置。
- flip()方法: 将buffer对象从写模式进行反转, 过程为将position指针调回原本的位置, 将limit指针调整到position指针的位置。
- 读数据: 首先调用flip()方法, 然后就进入了读模式。
- position指针移动到limit指针, 将全部数据读入。调用clear()方法将position指针移动到初始位置, limit指针移动到capacity位置。相当于调整回写模式。
- position指针向limit指针移动, 但是未完全读取完毕。调用compact()方法, 将剩余的内容拷贝到栈的开头, 类似于覆盖的方式使剩余内容可以在下一轮用同样方式调取。
Channel操作
FileChannel
- NoBufferStreamCopy
javaprivate 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); } }- BufferedStreamCopy
javapublic 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); } }- NioBufferCopy
javapublic 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); } }- NioTransferCopy
javapublic 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); } }ServerSocketChannel
SocketChannel
Selector
- 注册过程: Channel -> Selector -> SelectionKey
- interestOps(): (对于这个SelectionKey)检测该Channel是否为可读状态
- readyOps(): 检测Channel处于哪些可操作状态下
- channel(): 返回该key对应的channel
- selector(): 检测有多少Channel处于Selector监听的可操作状态上。
- attachment(): 将一个对象或者更多的信息附着到SelectionKey上
异步 I/O (AIO)
Async(Server)SocketChannel操作
方法
- connect/accept ->
implements CompletionHandler<AsynchronousSocketChannel, Object>(回调函数) - read -> buffer, attachment, handler
- write
Future
CompletionHandler
Tomcat结构
- Server -> (一对多)Service -> (一对多)Connector -> Processor -> Engine
- Server使Tomcat服务器最顶层组件, 负责加载服务器资源和环境变量
- Service集合Connector和Engine的抽象组件, 一个Service可以包含多个Connector和一个Engine
- Connector提供基于不同特定协议的实现, 接受解析请求, 返回响应
- 经Processor派遣请求至Engine进行处理
- Engine是容器的顶层组件, 容器使Tomcat用来处理请求的组件, 容器内部的组件按照层级排列
- Host代表一个虚拟主机, 一个Engine可以支持对多个虚拟主机的请求, Engine通过解析请求来决定将请求发送给哪一个Host
- Context代表一个Web Application, 应用资源管理, 应用类加载, Servlet管理, 安全管理等
- Wrapper是容器最底层的组件, 用于包裹住Servlet实例, 负责管理Servlet实例的生命周期