zoukankan      html  css  js  c++  java
  • Java NIO之通道Channel

    channel与流的区别:

    • 流基于字节,且读写为单向的。
    • 通道基于快Buffer,可以异步读写。除了FileChannel之外都是双向的。

    channel的主要实现:

    • FileChannel
    • DatagramChannel:UDP读写
    • SocketChannel:TCP读写
    • ServerSocketChannel

    支持scatter/gather(分散和聚集)

          1. 分散(scatter)从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。
            聚集(gather)写入Channel是指在写操作时将多个buffer的数据写入同一个Channel,因此,Channel 将多个Buffer中的数据“聚集(gather)”后发送到Channel。
    ByteBuffer header = ByteBuffer.allocate(128);
    ByteBuffer body   = ByteBuffer.allocate(1024);
    ByteBuffer[] bufferArray = { header, body };
    channel.read(bufferArray);

    通道的创建:

    除了FileChannel之外,都使用open创建。

    FileChannel的创建如下:

    RandomAccessFile aFile = new RandomAccessFile("data/nio-data.txt", "rw");
    FileChannel inChannel = aFile.getChannel();

    Socket通道

    分别对应java.net包中的Socket对象ServerSocket、Socket和DatagramSocket;Socket通道被实例化时,都会创建一个对等的Socket对象。

    Socket通道可以运行非阻塞模式并且是可选择的,非阻塞I/O与可选择性是紧密相连的,这也正是管理阻塞的API要在 SelectableChannel中定义的原因。设置非阻塞非常简单,只要调用configureBlocking(false)方法即可。如果需要中 途更改阻塞模式,那么必须首先获得blockingLock()方法返回的对象的锁。

    ServerSocketChannel实例:

    1. 使用对等socket来bind监听。

    2. 非阻塞状态下,accept在无连接时立即返回null

    ByteBuffer buffer = ByteBuffer.wrap("Hello World".getBytes());
    ServerSocketChannel ssc = ServerSocketChannel.open();
    ssc.socket().bind(new InetSocketAddress(12345));
    ssc.configureBlocking(false);
    for (;;) {
        System.out.println("Waiting for connections");
        SocketChannel sc = ssc.accept();
        if (sc == null)
           TimeUnit.SECONDS.sleep(2000);
       else {
            System.out.println("Incoming connection from:" + sc.socket().getRemoteSocketAddress());
            buffer.rewind();
            sc.write(buffer);
            sc.close();
        }
    }
    • SocketChannel 
             相对于ServerSocketChannel,它扮演客户端,发起到监听服务器的连接,连接成功后,开始接收数据。 
             调用它的open()方法仅仅是打开但并未连接,要建立连接需要紧接着调用connect()方法;也可以两步合为一步,调用open(SocketAddress remote)方法。 
             你会发现connect()方法并未提供timout参数,作为替代方案,你可以用isConnected()、isConnectPending()或finishConnect()方法来检查连接状态。
    • 1. isConnected判断是否已经建立
    • 2. finishConnect在非阻塞套接字上阻塞等待连接成功

    非阻塞的read在无数据时立即返回0

    •  
    • DatagramChannel 
             它是无连接的,它既可以作为服务器,也可以作为客户端。

     

  • 相关阅读:
    1.淡入淡出效果js原生代码2.缓冲运动
    php 图片加水印插件
    php redis使用 常用方法 | Windows环境下安装Redis | Windows下php安装redis扩展(详解版)
    Windows下安装使用workman简单实例
    极简生成excel方法;excel表导入数据库
    php 生成表单 | url串禁止转义并解决中文字符乱码
    图片上传预览并保存图片 | 多图上传预览并保存图片 | 树状结构(jquery.treeview.js)
    php Rsa签名算法
    php 正则表达式 1.字符串中提取带小数点的数字 2.判断字符串中是否包含关键字 3.统计二维数组中某个字段值出现的次数
    虚拟主机部署tp项目,在.htaccess文件中隐藏index.php
  • 原文地址:https://www.cnblogs.com/dorothychai/p/4178646.html
Copyright © 2011-2022 走看看