浅谈Nio编程

1.NIO提供了与传统BIO模型中的Socket和ServerSocket相对SocketChannelServerSocketChannel两种不同的套接字通道实现, 新增的着两种通道都支持阻塞和非阻塞两种模式。

2.缓冲区 Buffer,Buffer是一个对象,包含一些要写入或者读出的数据。 在NIO库中,所有数据都是用缓冲区处理的。在读取数据时,它是直接读到缓冲区中的;在写入数据时,也是写入到缓冲区中。任何时候访问NIO中的数据,都是通过缓冲区进行操作。缓冲区实际上是一个数组,并提供了对数据结构化访问以及维护读写位置等信息。

3.Selector一般称为选择器,也可以翻译为多路复用器,它是java Nio核心组件中的一个,用于检查一个或多个Nio Channel(通道)的状态是否处于可读,可写,如此可以实现单线程管理多个channels,也就是可以管理多个网络链接。

3.1. 使用Selector的好处在于:使用更少的线程就可以处理通道了,相比于使用多个线程,避免了线程上下文切换带来的开销。

代码部分:

import org.junit.Test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
public class SelectorDemo1  {
    //客户端代码
    @Test
    public void clientDemo() throws Exception{
        //1.获取通道,绑定主机和端口号
        SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8180));
        //2.切换到非堵塞模式
        socketChannel.configureBlocking(false);
        //3.创建buffer
        ByteBuffer writeBuffer = ByteBuffer.allocate(1024);
        //4.写入buffer数据(写入当前时间)
        writeBuffer.put(new Date().toString().getBytes());
        //5.模式切换
        writeBuffer.flip();
        //6.写入通道
        socketChannel.write(writeBuffer);
        //7.关闭通道
        socketChannel.close();
    }
    //服务端代码
    @Test
    public void serverDemo() throws IOException {
        //1.获取服务端通道
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //2.切换非阻塞模式
        serverSocketChannel.configureBlocking(false);
        //3.绑定端口号
        serverSocketChannel.bind(new InetSocketAddress(8180));
        //4.获取selector选择器
        Selector selector = Selector.open();
        //5.通道注册到选择器上,进行监听
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        //6.选择器进行轮询,进行后续操作
        while(selector.select()>0){
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            //遍历
            Iterator<SelectionKey> selectionKeyIterator = selectionKeys.iterator();
            while(selectionKeyIterator.hasNext()){
                SelectionKey next = selectionKeyIterator.next();
                if(next.isAcceptable()){
                    //获取连接
                    SocketChannel accept = serverSocketChannel.accept();
                    //切换非阻塞模式
                    accept.configureBlocking(false);
                    //注册
                    accept.register(selector,SelectionKey.OP_READ);
                }else if(next.isReadable()){
                    SocketChannel channel = (SocketChannel)next.channel();
                    ByteBuffer readBuffer = ByteBuffer.allocate(1024);
                    //读取数据
                    int length = 0;
                    while((length = channel.read(readBuffer))>0){
                        readBuffer.flip();
                        System.out.println(new String(readBuffer.array(),0,length));
                        readBuffer.clear();
                    }
                }
            }
            selectionKeyIterator.remove();
        }
        serverSocketChannel.close();
    }
}

小结:

JAVA NIO:称为非阻塞IO,读写的过程中不会发生阻塞线程,我们之前所学习的流,称为BIO,阻塞是IO(通过accpet方法等待接收),就是在读写的过程中可能会发生阻塞现象。

非阻塞IO面向Channel("通道")的,不是面向Stream(流)的。

流的特点:方向单一,顺序读写。流要么是输入流用于顺序读取数据,要么是输出流用于顺序写出数据

Channel的特点:双向的,既可以读又可以写

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值