java NIO

java NIO 同步非阻塞IO

三大组件

  • Buffer

buffer 用来存储数据,对8中基本类型有7中buffer 实现,ByteBuffer,ShortBuffer,IntBuffer,CharBuffer,FloatBuffer,DoubleBuffer,LongBuffer,对于boolean ,可以使用其他方式表示,0 表示false 1 表示true
Buffer 的三个要素 ,position(对buffer 进行 get ,put 操作时position 会自动向后移动) , limit(buffer 可以操作的极限范围) ,capctiy(buffer 的容量),三者的关系 position<= limit<=capctiy

  • Channel

channel 用来传输数据,传输单位为 buffer,BIO 只能单向传输数据,但是NIO 可以双向传输数据,可以通过 buffer.flip()函数进行切换
常见的Channel
. FileChannel
. UDPChannel: DatagramChannel
. TCPChannel: SocketChannel, ServerSocketChannel
如果不设置,channel 默认时阻塞的,可以通过
channel.configureBlocking(false); 设置为非阻塞

  • Selector

多路复用选择器

package server;

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;

public class ServerChannel {
    public static void main(String[] args) throws IOException {
        //创建serverSocketChannel
        ServerSocketChannel ssc = ServerSocketChannel.open();
        ssc.configureBlocking(false);
        // 绑定端口
        ssc.bind(new InetSocketAddress(8088));

        Selector selc = Selector.open();
        SelectionKey register = ssc.register(selc, SelectionKey.OP_ACCEPT);
        while(true){
            selc.select();
            Set<SelectionKey> selectionKeys = selc.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            while(iterator.hasNext()){
                SelectionKey selectionKey = iterator.next();
                if(selectionKey.isAcceptable()){
                    //接受事件
                    ServerSocketChannel socketChannel = (ServerSocketChannel) selectionKey.channel();
                    SocketChannel sc = socketChannel.accept();
                    sc.configureBlocking(false);
                    //注册可读可写事件
                    sc.register(selc,SelectionKey.OP_READ+SelectionKey.OP_WRITE);
                }
                if(selectionKey.isReadable()){
                    SocketChannel sc  = (SocketChannel) selectionKey.channel();
                    sc.configureBlocking(false);
                    sc.register(selc,SelectionKey.OP_READ);
                    ByteBuffer bb = ByteBuffer.allocate(1024);
                    sc.read(bb);
                    System.out.println(new String(bb.array(),0,bb.position()));
                    //从selector 中移除写事件
                    sc.register(selc,selectionKey.interestOps()-SelectionKey.OP_READ);
                }
                if(selectionKey.isWritable()){
                    SocketChannel sc  = (SocketChannel) selectionKey.channel();
                    sc.configureBlocking(false);
                    //写出数据
                    sc.write(ByteBuffer.wrap("hello client".getBytes(StandardCharsets.UTF_8)));
                    // 从selector 中移除写事件
                    sc.register(selc,selectionKey.interestOps()-SelectionKey.OP_WRITE);

                }
            }
            iterator.remove();
        }

    }
}
package client;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.StandardCharsets;

public class ClientChannel {
    public static void main(String[] args) throws IOException {
        //打开 socketChannel
        SocketChannel sc = SocketChannel.open();

        // 获取连接
        sc.connect(new InetSocketAddress("localhost", 8088));

        //定义buffer
        ByteBuffer bb = ByteBuffer.wrap("hello server".getBytes(StandardCharsets.UTF_8));

        //发送数据
        sc.write(bb);

        ByteBuffer b = ByteBuffer.allocate(1024);
        sc.read(b);
        byte[] array = b.array();
        System.out.println(new String(array,0,b.position()));
        //关闭通道
        sc.close();

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值