zoukankan      html  css  js  c++  java
  • JAVA_NIO通信理论基础

    java的NIO

    包含通道Channel,缓冲区Buffer,选择器selector三个重要的类。

    IO多路复用

    指的是一个进程/线程可以同时监视多个文件描述符(一个网络连接,操作系统底层使用一个文件描述符来表示),一旦其中的一个或者多个文件描述符可读或者可写,系统内核就通知该进程/线程。

    缓冲区Buffer

    Buffer是抽象类,Buffer类是一个非线程安全类, 主要数据类型有 ByteBuffer、CharBuffer、DoubleBuffer、FloatBuffer、IntBuffer、LongBuffer、ShortBuffer、MappedByteBuffer(用于内存映射)。

    capacity属性指容量,写入的数据对象的数量一旦初始化,就不能再改;

    position属性表示当前位置,读写模式变化时,position会进行调整;limit属性表示读写的最大上限,读写模式切换时变化。

    属性mark(标记)就是相当一个暂存属性,暂时保存position的值,方便后面的重复使用position值。

    allocate()创建缓冲区, put()写入到缓冲区,flip()翻转(将写入模式翻转成读取模式),get()从缓冲区读取,rewind() 倒带(重新读取,positon=0,mark清除),

    Buffer.mark()方法的作用是将当前position的值保存起来,放在mark属性中,让mark属性记住这个临时位置;

    之后,可以调用Buffer.reset()方法将mark的值恢复到position中,clear( )清空缓冲区。

     通道Channel

    通道可以表示一个底层的文件描述符,例如硬件设备、文件、网络连接等。FileChannel(阻塞,文件IO读写)、SocketChannel(TCP连接读写)、ServerSocketChannel(服务器监听TCP连接的通道)、DatagramChannel(UDP协议数据读写)。

    获取File通道

    输入输出流 -> getChannel() -> FileChannel,读取:int read(ByteBuffer buf)(写入缓冲区),(缓冲区翻转 flip)写入通道:int write(ByteBuffer buf)(读取缓冲区),关闭通道,close(),刷盘:channel.force(true)方法,强制刷新到磁盘。

    高效文件复制transferFrom方法。不可以被选择器选择,没有非阻塞模式。

    SocketChannel传输通道

    静态方法 open() 获得 SocketChannel -> 设置为非阻塞模式 -> connect(ip,port)发起连接,判断 finishConnect() ? 是否完成连接。TCP

    ServerSocketChannel通道

    监听套接字的 accept()方法,来获取新连接的套接字通道:server.accept()->SocketChannel->设置非阻塞模式。read,flip,write, shutdownOutput()发送-1 终止标记,close。用Selector通道选择器判断通道何时可读。TCP

    DatagramChannel数据报通道

    open静态方法得 channel->channel.configureBlocking(false)方法,设置成非阻塞模式->接收数据,调用bind方法绑定数据报的监听端口channel.socket().bind() -->

    读取 receive(ByteBuffer buf)-> flip() 切换读取buf -> send(buf,new Obj(ip,port))->clear切换写入buf->close关闭。UDP

    Selector选择器

    选择器的使命是完成IO的多路复用。一个通道代表一条连接通路,通过选择器可以同时监控多个通道的IO(输入输出)状况。选择器和通道的关系,是监控和被监控的关系。

    Channel.register(Selector sel, int ops)方法将通道实例注册到一个选择器中。

    监听事件

    可读:SelectionKey.OP_READ,可写:SelectionKey.OP_WRITE,连接就绪(完成握手连接): SelectionKey.OP_CONNECT,接收就绪(新连接到来):SelectionKey.OP_ACCEPT

    SelectableChannel可选择通道

    FileChannel文件通道就不能被选择器复用,前提:判断它是否继承了抽象类SelectableChannel(可选择通道).。

    SelectionKey选择键

    一旦在通道中发生了某些IO事件(就绪状态达成),并且是在选择器中注册过的IO事件,就会被选择器选中,并放入SelectionKey选择键的集合中。简单地理解为:选择键,就是被选中了的IO事件。

    选择器使用流程

    Selector.open() 静态工厂方法 -> 实例channel.register(Selector sel, int ops)(channel必须设置非阻塞模式)

    注意:一个通道,并不一定要支持所有的四种IO事件 -> 选出感兴趣的IO就绪事件, selector.select()-> 选出已经注册的、已经就绪的IO事件,

    保存到SelectionKey选择键集合中 -> selector.selectedKeys() ->Set<SelectionKey  -> iterator: SelectionKey  ->IO事件对应业务处理->最后 iterator.remove当前key。

    查询重载方法

    select(): 阻塞调用, select(long timeout) 阻塞或指定时长,selectNow():非阻塞,不管有没有IO事件,都会立刻返回;

    select() 方法返回的整数值(int整数类型),表示 2次 查询之间发生了IO事件的通道数量。

    读书笔记

    阅读: 《Netty、Redis、Zookeeper高并发实战》

  • 相关阅读:
    Linux之Ubuntu添加/移除个人软件包存档的源[PPA,Personal Package Archives]
    [C++]Linux之头文件sys/types.h[/usr/include/sys]
    [C++]Linux之文件拷贝在系统调用和C库函数下的效率比较
    Linux之Ubuntu下安装屏幕录像软件(SimpleScreenRecorder)【摘抄】
    [C++]基于Curses库的实时系统监测可视化系统-2017-12-09 15-07-42
    [C++]Linux之虚拟文件系统[/proc]中关于CPU/内存/网络/内核等的一些概要性说明
    [C++]Linux之计算内存利用率与辨析
    [C++]Linux之网络实时检测功能
    [C++]Linux之C编程异常[true未定义解决方案]
    [C++]Linux之读取计算机网络数据[/proc/net/dev]
  • 原文地址:https://www.cnblogs.com/wangrq/p/JAVA-NIO-0001.html
Copyright © 2011-2022 走看看