IO流

  • 定义 : Java 中把不同的 输入/ 输出源 ,抽象的表示成(steam
  • 好处 : 因为Java 中提供IO流的抽象,所以开发者 可以采用一致的IO代码 读写各种各样的IO流节点
  • 分类
    • 1、按照流向 可以分为 输入流 、输出流

      • 输入流 : 只能从中读取数据,不能往里面写入数据
      • 输出流 : 只能从中写入数据,不能往里面读取数据
    • 2、按照操作的数据单元不同,可以分为 字节流、字符流

      • 字节流 : 操作的数据单元是 8位的字节,以InputSteam和OutputSteam 作为基类
      • 字符流 : 操作的数据单元是16位的字符,以Reader 和 Writer 作为基类
    • 3、按照流的角色来分 分为 节点流 和 字符流

      • 节点流 : 程序直接操作的数据源的流
      • 处理流 : 对流进行了包装,程序并没有直接操作数据流
    • 使用处理流的好处
      Java 中的处理流来包装节点流 是 典型的 装饰器设计模式,通过使用处理流来包装节点流,可以消除不同的节点流之间的差异,也可以更加方便的完成输入输出功能

      • 性能的提高 : 增加了 缓冲的方式 来提高 输入/输出 的效率
      • 操作的便捷 :处理流提供便捷的方式 一次输入/输出大量的数据

Java中网络编程的IO模型

BIO模型 (面向流(Stream)
  • BIO模型是一种 同步阻塞模型,服务器 实现模式是 一个连接一个线程
    每当有一个客户端连接 就需要分配一个线程去处理,对性能开销特别大
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
  • 总结BIO通信流程
    • 服务端 启动一个ServerSocket注册端口,调用accept方法,监听客户端的请求
    • 客户端启动Socket 绑定Ip地址和端口,对服务器进行通信,默认情况下,一个客户端的通信,需要服务端启动一个线程来对应处理

NIO模型 (面向缓冲区)

NIO模型是一种支持非阻塞式IO通信的模型
三大组成 通道Channel 缓冲区Buffer 选择器Selector

  • Channel : 负责通信的连接
  • Buffer : 负责传输数据
  • Selector : 是一个NIO组件,负责管理Channel
    在这里插入图片描述

NIO非阻塞式网络通信原理分析

服务端流程

  • 1、当客户端连接服务端时,服务端会通过 ServerSocketChannel 得到 SocketChannel:1. 获取通道
ServerSocketChannel ssChannel = ServerSocketChannel.open();
  • 2、切换非阻塞模式
 ssChannel.configureBlocking(false);
  • 3、绑定连接
ssChannel.bind(new InetSocketAddress(9999));
  • 4、 获取选择器
Selector selector = Selector.open();
  • 5、 将通道注册到选择器上, 并且指定“监听接收事件”
ssChannel.register(selector, SelectionKey.OP_ACCEPT);
  • 读 : SelectionKey.OP_READ (1)

  • 写 : SelectionKey.OP_WRITE (4)

  • 连接 : SelectionKey.OP_CONNECT (8)

  • 接收 : SelectionKey.OP_ACCEPT (16)

  • 6.轮询式的获取选择器上已经“准备就绪”的事件

//轮询式的获取选择器上已经“准备就绪”的事件,没有事件时候select阻塞
 while (selector.select() > 0) {
        
        //7. 获取当前选择器中所有注册的“选择键(已就绪的监听事件)”
        Iterator<SelectionKey> it = selector.selectedKeys().iterator();
        
        while (it.hasNext()) {
            //8. 获取准备“就绪”的是事件
            SelectionKey sk = it.next();
            //9. 判断具体是什么事件准备就绪
            if (sk.isAcceptable()) {//如果是连接事件
                //10. 若“接收就绪”,获取客户端连接
                SocketChannel sChannel = ssChannel.accept();
                //11. 切换非阻塞模式
                sChannel.configureBlocking(false);
                //12. 将该通道注册到选择器上
                sChannel.register(selector, SelectionKey.OP_READ);
            } else if (sk.isReadable()) {
                //13. 获取当前选择器上“读就绪”状态的通道
                SocketChannel sChannel = (SocketChannel) sk.channel();
                //14. 读取数据
                ByteBuffer buf = ByteBuffer.allocate(1024);
                int len = 0;
                while ((len = sChannel.read(buf)) > 0) {
                    buf.flip();
                    System.out.println(new String(buf.array(), 0, len));
                    buf.clear();
                }
            }
            //15. 取消选择键 SelectionKey
            it.remove();
        }
    }
}

客户端流程

  • 1.获取通道
SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9999));
  • 2.切换非阻塞模式
sChannel.configureBlocking(false);

3.分配指定大小的缓冲区

ByteBuffer buf = ByteBuffer.allocate(1024);
  • 4.发送数据给服务端
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
	String str = scan.nextLine();
	buf.put((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(System.currentTimeMillis())
			+ "\n" + str).getBytes());
	buf.flip();
	sChannel.write(buf);
	buf.clear();
}
//关闭通道
sChannel.close();

AIO模型

AIO是一种异步非阻塞的模型
异步非阻塞,服务器实现模式为一个有效请求一个线程,客户端的I/O请求都是由OS先完成了再通知服务器应用去启动线程进行处理
可以理解为,read/write方法都是异步的,完成后会主动调用回调函数

三种模型的适用场景分析

  • BIO方式适用于连接数目比较小且固定的架构,这种方式对服务器资源要求比较高,并发局限于应用中
  • NIO方式适用于**连接数目多且连接比较短(轻操作)**的架构,比如聊天服务器,并发局限于应用中,编程比较复杂
  • AIO方式使用于**连接数目多且连接比较长(重操作)**的架构,比如相册服务器,充分调用OS参与并发操作,编程比较复杂
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值