1.netty介绍

1.介绍

  1. 是JBOSS通过的java开源框架
  2. 是异步的,基于事件驱动(点击一个按钮调用某个函数)的网络应用框架,高性能高可靠的网络IO程序
  3. 基于TCP,面向客户端高并发应用/点对点大量数据持续传输的应用
  4. 是NIO框架 (IO的一层层封装) TCP/IP->javaIO和网络编程–>NIO—>Netty

2.应用场景

  1. 互联网 RPC框架比如阿里的Dubbo
  2. 网络游戏 可以定制TCP/UDP 和http协议栈
  3. 大数据 hadoop序列化组件和实时数据文件共享 AVRO
    还有Flink Spark Akka…其他开源项目

3.IO模型

  1. BIO(blocking原生javaIO,阻塞性,一个连接需要一个线程处理,连接不使用阻塞也占用线程)
    //面试: 适用连接数目少架构稳定的,对服务器资源要求高,但程序简单容易理解 jdk1.4之前唯一的选择
  2. NIO(No blocking/new 同步非阻塞)(一个线程使用selector维护多个客户端,轮询检测活动 多路复用,可以开多个线程) 图1nettyNIO原理、
    请添加图片描述

//适用 连接数目多且连接比较短的(轻操作)的结果 比如聊天,弹幕,服务器之间通信,编程复杂 jdk1.4开始支持
3. AIO(等待时间长才需要异步,异步非阻塞) 是有效请求才启动线程
//面试: 适合;连接数量多且连接长的, 比如相册服务器.编程复杂,jdk7开始支持

4.BIO实例(可以使用线程池改善)

win的 telnet 127.0.0.1 6666端口的ctrl+]的send xxx可以发送数据到服务器

5.NIO

  1. 结构 如果通道没有事件,选择器不处理,线程也不阻塞 selector(选择器)<–>channel(通道)<—> buffer(缓冲区,数据先在这里实现了非阻塞)<—>socket //IntBuffer的使用
    java除了boolean类型,是类型统一管理,所以比BIO更快 //!!!一定要flip()读写切换 才能读取值
  2. 关系
    1.buffer是内存块(面向缓冲/块的编程),是一个数组,达到一定量才给channel
    2.selector由哪个channel有事件才切换过去的,不是自动切换的 ?
    3.buffer channel是双向的,区别BIO 有in output流
    4.一个thread对应一个selector,对应多个channel

6.Buffer的属性

position
filp()会使他变为0,读写的时候也会改变,一直往后移
limit(块的最大容量) 和capacity(自己设置的块容量)一样用来判断是否超出范围 capacity 自己设置的数组容量 mark 标记

//常用的api

IntBuffer in=IntBuffer.allocate(5);//5个容量 
                                   .flip //读写切换,如果是读的可以切换为写的,所以说NIO是双向的
                                  .position(1);//设置读写的位置
                                  .limit(3);//设置读写限制个数<3
                                  .get(); //得到元素通过iterator
                                  .put(1);
                                  .put(1,1);//在指定位置放数据
                                  .clear();//清除缓冲器 
                                  .hasRemain();//相当于hasNext()
                                  .isReadOnly();//是否为只读缓冲区
                                  //抽象方法jdk1.6引入 hasArray()缓冲区是否可访问底层的buffer数组 array()返回buffer数组
                                 //常用ByteBuffer

7.Channel 可以向buffer读写和拷贝

1.ServerSockerChannel 类似ServerSocker,SockerChannel就是Socket,还有一模一样的UDP的类
2.FileChannel类
  read() 通道读数据到buffer write() buffer写入通道 transferFrom()目标通道复制到本通道 transferTo() channel复制到目标通道

8.使用channel生成文件,与BIO的关系,底层就是BIO

          String str="aaa";
         out=new FileOutputStream("d;\\aaa.txt"); //输出流包括channel
          FileChannel channel=out.getChannel();

            byteBuffer=ByteBuffer.allocate(1024);
            byteBuffer.put(str.getBytes);
            byteBuffer.flip(); //初始状态是读,切换成写
            channel.write(byteBuffer);//向其他通道写
            out.close();//关闭流
public class bufferDemo {
    public static void main(String[] args) throws IOException {
        String str="helloworld";

        FileOutputStream out = new FileOutputStream("D:\\abs.txt");
        FileChannel channel = out.getChannel();
        ByteBuffer byteBuffer=ByteBuffer.allocate(1024);
        byteBuffer.position(2);
        byteBuffer.put(str.getBytes()); //放在limit后面会报错,这个是限制容量
        //相当于截断写入的数据
        byteBuffer.limit(7);

        //必须要写
        byteBuffer.flip();
        channel.write(byteBuffer);
        channel.close();
        out.close();


    }
}

9.读数据

      File file=new File("d:\\aa.txt");
        in=new FileInputStream(file);
         fileChannel=in.getChannel();
         byteBuffer= ByteBuffer.allocate((int)file.length());
         fileChannel.read(byteBuffer);
              sout(new String(  byteBuffer.array()));
               in.close();
public class bfDemo {
    public static void main(String[] args) throws IOException {
        File file = new File("D:\\abs.txt");
        FileInputStream inputStream = new FileInputStream(file);
        FileChannel channel = inputStream.getChannel();
        ByteBuffer byteBuffer = ByteBuffer.allocate((int) file.length());
        channel.read(byteBuffer);

            System.out.println(new java.lang.String(byteBuffer.array()));


    }
}

10.一个buffer 多个channel(创建两个流)拷贝文件 边读边写
//在java写路径相对位置是 本项目最父类的项目路径!!!(以前写相对路径总是出错)
//必须需要不然position=limit

      byteBytebuffer.clear();
                             .flip();
     public class bfDemo3Copy {
    public static void main(String[] args) throws IOException {
        FileInputStream inputStream = new FileInputStream("D:\\abs.txt");
        FileChannel c1 = inputStream.getChannel();
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\abs1.txt");
        FileChannel c2 = fileOutputStream.getChannel();
        ByteBuffer allocate = ByteBuffer.allocate(inputStream.available());
        c1.read(allocate);
        allocate.flip();
        c2.write(allocate);

    }

}

//一块一块读,反转写入.steps are combinate bytes to buffer and send to another channel(outputStream)

public class NIOFileChannel03 {
    public static void main(String[] args) throws Exception {

        FileInputStream fileInputStream = new FileInputStream("1.txt");
        FileChannel fileChannel01 = fileInputStream.getChannel();

        FileOutputStream fileOutputStream = new FileOutputStream("2.txt");
        FileChannel fileChannel02 = fileOutputStream.getChannel();

        ByteBuffer byteBuffer = ByteBuffer.allocate(512);

        while (true) { //循环读取
            byteBuffer.clear(); //清空buffer!!!
            int read = fileChannel01.read(byteBuffer);
            System.out.println("read =" + read);
            if(read == -1) { //表示读完
                break;
            }
            //将buffer 中的数据写入到 fileChannel02 -- 2.txt
            byteBuffer.flip();
            fileChannel02.write(byteBuffer);
        }

        //关闭相关的流
        fileInputStream.close();
        fileOutputStream.close();
    }
}

11.拷贝图片

     destch.transferFrom(sourceCh,0,sourceCh.size());
    //关闭所有通道和流
public class bfDemo4transferCopy {
    public static void main(String[] args) throws IOException {
        FileInputStream inputStream = new FileInputStream("D:\\abs.txt");
        FileChannel c1 = inputStream.getChannel();
        FileOutputStream fileOutputStream = new FileOutputStream("D:\\abs3.txt");
        FileChannel c2 = fileOutputStream.getChannel();
        c2.transferFrom(c1,0,c1.size());
    }
}

12.buffer放的顺序和取的顺序一样不然抛出异常BufferUnderflowException

  ByteBuffer bf= ByteBuffer.allocate(64);
     bf.putInt(100); 
     bf.putLong(100L);
    bf.flip();
   bf.getInt(); 
     bf.getLong();

13.写完转为只读buffer
//12的代码

    buffer.asReadOnlyBuffer();public class OnlyWrite {
    public static void main(String[] args) {
        ByteBuffer bf= ByteBuffer.allocate(64);
        bf.putInt(100);
        bf.putLong(100L);
        bf.flip();
        ByteBuffer byteBuffer = bf.asReadOnlyBuffer();
        byteBuffer.getInt();
        byteBuffer.getLong();
        byteBuffer.putLong(10);//错误不能写,只能读
    }
}

14.MappedByteBuffer可以在堆外内存修改文件(效率高)操作系统不用拷贝一次到内存

access=new RandAccessFile("1.txt","rw");
 channel=access.getChannel();
map=channel.map(FileChannel.MapMode.READ_WRITE,0,5);模式,开始位置,结束位置 <5byte
   map.put(0,(byte)'H'); //在内存直接修改文件内容,然后放回磁盘
  access.close();
 public class MapBuffer {
    public static void main(String[] args) throws IOException {
        RandomAccessFile access = new RandomAccessFile("1.txt", "rw");
        FileChannel channel = access.getChannel();
        //到内存修改的大小范围是 0-5, if out of the bound will throw an expection
        MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, 5);
        map.put(0,(byte)'A');
        map.put(4,(byte)'H');

        access.close();
        System.out.println("修改成功");
    }
}

//idea需要在文件夹外打开,不然看不到效果

15.分散和聚集 scatter(写的时候放到多个buffer[数组array])和gather(读的时候多个buffer) 加快读写效率(the key is using many buffer to read and read)(read and write only once that can get more buffer)

  
public class scatterAndGather {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocket =  ServerSocketChannel.open().bind(new InetSocketAddress(6666));
        ByteBuffer[] byteBuffers= new ByteBuffer[2];
        byteBuffers[0]=ByteBuffer.allocate(3);
        byteBuffers[1]=ByteBuffer.allocate(5);

        SocketChannel accept = serverSocket.accept();
        int msgLen=8;
       while (true){
           int byteRead=0;
          while (byteRead<msgLen){

              long read = accept.read(byteBuffers);
              byteRead++;
              System.out.println("bufferRead:"+byteRead);
              Arrays.asList(byteBuffers).stream()
                      .map(
                              buffer->"position"+buffer.position()+
                                      ",limit="+buffer.limit()
                      )
                              .forEach(System.out::println);



          }
           Arrays.asList(byteBuffers).stream().forEach(buffer ->buffer.flip() );
          long byteWrite=0;
          while (byteWrite<msgLen){
              //一次读出多少个字节
              long l=accept.write(byteBuffers);
              byteWrite+=l;
              System.out.println(byteWrite);
          }
          Arrays.asList(byteBuffers).forEach(byteBuffer -> {
              System.out.println(new String(byteBuffer.array() ));
              byteBuffer.clear();});
           System.out.println("byteRead:="+byteRead+"byteWrite:"+byteWrite+"msgLen:"+msgLen);

       }


    }
}

16.selector管理多个连接(channel) 不停如轮询检测事件,有事件处理,阻塞不等待,处理其他通道的请求,解决了多线程单通道的问题,提高了性能

   selector类selects()//得到channel的连接的selectkey集合阻塞,
  selector.select(1000)//阻塞1000毫秒,必须返回数据
  selector.wakeup()//唤醒selector,阻塞中可以唤醒
  selector.selectNow()//非阻塞,立即返回结果,核心方法
           selector.selectedKeys() //select获取绑定channel产生事件的selectkey集合
//可以注册channel到selector上返回selectionKey  (集合)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/52031.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文讲清楚地图地理坐标系

前言 我最近在做一个和地图有关的项目&#xff0c;这里本人地图采用的是mapbox&#xff0c;其中涉及一个功能需要根据用户输入的地点直接定位到地图上的对应的位置&#xff0c;本人开始想的是直接调用百度的接口根据地名直接获取坐标&#xff0c;发现在地图上的位置有偏移不够…

一、Postfix[安装与配置、smtp认证、Python发送邮件以及防垃圾邮件方法、使用腾讯云邮件服务]

Debian 11 一、安装 apt install postfix 二、配置 1.dns配置 解释&#xff1a;搭建真实的邮件服务器需要在DNS提供商那里配置下面的dns 配置A记录mail.www.com-1.x.x.x配置MX记录www.com-mail.www.com 解释&#xff1a;按照上面的配置通常邮件格式就是adminwww.com其通过…

使用BERT分类的可解释性探索

最近尝试了使用BERT将告警信息当成一个文本去做分类&#xff0c;从分类的准召率上来看&#xff0c;还是取得了不错的效果&#xff08;非结构化数据强标签训练&#xff0c;BERT确实是一把大杀器&#xff09;。但准召率并不是唯一追求的目标&#xff0c;在安全场景下&#xff0c;…

python 自动化数据提取之正则表达式

>>>> 前 言 我们在做接口自动化的时候&#xff0c;处理接口依赖的相关数据时&#xff0c;通常会使用正则表达式来进行提取相关的数据&#xff0c;今天在这边和大家聊聊如何在python中使用正则表达式。 正则表达式&#xff0c;又称正规表示式、正规表示法、正规…

K8S:容器日志收集与管理

Kubernetes 里面对容器日志的处理方式&#xff0c;都叫作 cluster-level-logging&#xff0c;即&#xff1a;这个日志处理系统&#xff0c;与容器、Pod 以及 Node 的生命周期都是完全无关的。这种设计当然是为了保证&#xff0c;无论是容器挂了、Pod 被删除&#xff0c;甚至节点…

RabbitMQ部署指南

RabbitMQ部署指南 1.单机部署 我们在Centos7虚拟机中使用Docker来安装。 1.1.下载镜像 方式一&#xff1a;在线拉取 docker pull rabbitmq:3-management方式二&#xff1a;从本地加载 已经提供了镜像包&#xff1a; 上传到虚拟机中后&#xff0c;使用命令加载镜像即可&…

文档管理NAS储存安全吗?

关键词&#xff1a;私有化、知识管理系统、文档管理、群晖NAS、协同编辑 随着企业不断发展扩大&#xff0c;企业的知识文档也逐渐增多&#xff0c;很多企业方便管理及考虑数据安全问题会将文件数据储存至NAS。 但将企业文档数据放在NAS上就足够安全的吗&#xff1f; 天翎文档管…

集成学习概述

集成学习 1. 集成学习概念 集成学习是解决有监督机器学习任务的一类方法,它的思路是基于多个学习算法的集成来提升预测结果,它通过多个模型的组合形成一个精度更高的模型,参与组合的模型成为弱学习器(基学习器)。训练时,使用训练集依次训练出这些弱学习器,对未知的样本…

yolov8系列[五]-项目实战-yolov8模型无人机检测

yolov8系列[五]-项目实战-yolov8模型无人机检测 项目介绍项目展示功能简介代码结构如何启动 开发者模式1. 安装依赖环境2. 启动程序 源代码下载其他 项目介绍 无人机识别项目,无人机搭载nvidia jetson边缘计算板子,进行实时识别。使用yolov8算法&#xff0c;训练了识别无人机的…

用于永磁同步电机驱动器的自适应SDRE非线性无传感器速度控制(MatlabSimulink实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f308;4 Matlab代码&Simulink仿真实现 &#x1f4a5;1 概述 本文方法基于状态依赖的里卡蒂方程&#xff08;SDRE&#xff09;控制技术及其梯度型神经网络的实时计算方法&#xff0c;允许…

c++里的基础类 is_empty_v<_Ty1>

&#xff08;1&#xff09;为什么要研究这个问题&#xff0c;因为包括智能指针等很多源代码里都会使用 _Compressed_pair 这个类&#xff0c;其是一对值。研究这个类&#xff0c;就牵涉另一个更基础的类 is_empty_v<_Ty1> &#xff08;2&#xff09; is_empty_v<_Ty1&…

APP自动化测试-Python+Appium+Pytest+Allure框架实战封装(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 pytest只是单独的…

西安电子科技大学

前言 本篇文章投稿与以下活动 【西安城市开发者社区】探索西安高校&#xff1a;展现历史与创新的魅力 资料参考与百度百科 学校简介 西安电子科技大学&#xff08;Xidian University&#xff09;&#xff0c;简称“西电”&#xff0c;位于陕西省西安市&#xff0c;是中央部…

二、SQL-5.DQL-8).案例练习

1、查询年龄为20,21,22,23岁的员工信息 select * from emp where age in(20, 21, 22, 23) and gender 女; 2、查询性别为男&#xff0c;并且年龄在20-40岁&#xff08;含&#xff09;以内的姓名为三个字的员工 select * from emp where gender 男 && age between 2…

ICLR 2023 | 用于分布外泛化的拓扑感知鲁棒优化

论文链接&#xff1a;https://openreview.net/pdf?idylMq8MBnAp 代码链接&#xff1a;GitHub - joffery/TRO: The Pytorch implementation for "Topology-aware Robust Optimization for Out-of-Distribution Generalization" (ICLR 2023) 01. 研究背景 近年来&…

Linux搭建Promtail + Loki + Grafana 轻量日志监控系统

一、简介 日志监控告警系统&#xff0c;较为主流的是ELK&#xff08;Elasticsearch 、 Logstash和Kibana核心套件构成&#xff09;&#xff0c;虽然优点是功能丰富&#xff0c;允许复杂的操作。但是&#xff0c;这些方案往往规模复杂&#xff0c;资源占用高&#xff0c;操作苦…

【Java基础教程】(四十四)IO篇 · 上:File类、字节流与字符流,分析字节输出流、字节输入流、字符输出流和字符输入流的区别~

Java基础教程之IO操作 上 &#x1f539;本节学习目标1️⃣ 文件操作类&#xff1a;File2️⃣ 字节流与字符流2.1 字节输出流&#xff1a;OutputStream2.2 字节输入流&#xff1a;InputStream2.3 字符输出流&#xff1a;Writer2.4 字符输入流&#xff1a;Reader2.5 字节流与字符…

S32K14x FlexNVM介绍(flexible Non-volatile memory)

S32K14x是一款NXP推出的32位汽车级微控制器&#xff0c;其存储结构相对复杂。下面是对其存储结构的中文介绍&#xff1a; S32K14x采用了分层存储结构&#xff0c;包括Flash存储器和SRAM存储器。Flash存储器用于存储程序代码和常量数据&#xff0c;而SRAM存储器用于存储变量数据…

《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(14)-Fiddler断点(breakpoints)实战,篡改或伪造数据

1.简介 上一篇主要就讲解和分享Fiddler断点的理论和操作&#xff0c;今天宏哥就用具体例子&#xff0c;将上一篇中的理论知识实践一下。而且在实际测试过程中&#xff0c;有时候需要修改请求或响应数据&#xff0c;或者直接模拟服务器响应&#xff0c;此时可以使用fiddler进行…

数据库—用户权限管理(三十三)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、概述 二、用户权限类型 ​三、用户赋权 四、权限删除 五、用户删除 前言 数据库用户权限管理是指对数据库用户的权限进行控制和管理&#xff0c;确保用户只能执…
最新文章