1.netty介绍

news2024/11/11 5:25:29

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.coloradmin.cn/o/812133.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HTTP请求走私漏洞简单分析

文章目录 HTTP请求走私漏洞的产生HTTP请求走私漏洞的分类HTTP请求走私攻击的危害确认HTTP请求走私漏洞通过时间延迟技术确认CL漏洞通过时间延迟技术寻找TE.CL漏洞 使用差异响应内容确认漏洞通过差异响应确认CL.TE漏洞通过差异响应确认TE.CL漏洞 请求走私漏洞的利用通过请求漏洞…

【面试题】与通义千问的芯片前端设计模拟面试归纳

这里是尼德兰的喵芯片设计相关文章,欢迎您的访问! 如果文章对您有所帮助,期待您的点赞收藏! 让我们一起为芯片前端全栈工程师而努力! 前言 两个小时,与chatGPT进行了一场数字IC前端设计岗的面试_尼德兰的喵的博客-CSDN博客 和GPT-3.5的回答可以对比品尝,味道更好。 模…

nacos源码打包及相关配置

nacos 本地下载后&#xff0c;需要 install 下&#xff1a; mvn clean install -Dmaven.test.skiptrue -Dcheckstyle.skiptrue -Dpmd.skiptrue -Drat.skiptruenacos源码修改后&#xff0c;重新打包生成压缩包命令&#xff1a;在 distribution 目录中运行&#xff1a; mvn -Pr…

数字化转型导师坚鹏:数字化时代扩大内需的8大具体建议

在日新月异的数字化时代、复杂多变的国际化环境下&#xff0c;扩大内需成为推动经济发展的国家战略&#xff0c;如何真正地扩大内需&#xff1f;结合本人15年的管理咨询经验及目前实际情况的深入研究&#xff0c;提出以下8大具体建议&#xff1a; 1、制定国民收入倍增计划。结…

QObject::connect: No such signal me::sendMsg(QString s) in ...

QObject::connect: No such signal me::sendMsg&#xff08;QString s&#xff09; in ... 解决方案 在使用qt4的connect中&#xff0c;爆的bug&#xff1a; 导致 teacher 的槽函数 receiveMsg(QString s) 一直没有被调用。。。。 解决方案 去掉参数名&#xff0c; 保留类型…

spring6——容器

文章目录 容器&#xff1a;IocIoc容器控制反转&#xff08;Ioc&#xff09;依赖注入IoC容器在Spring的实现 基于XML管理Bean搭建环境获取bean依赖注入setter注入构造器注入特殊值处理字面量赋值null值xml实体CDATA节 特殊类型属性注入为对象类型属性赋值方式一&#xff1a;引入…

Spring依赖注入和ioc在spring中的实现方式

目录 一、依赖注入 1.IOC思想 2.什么是依赖注入&#xff1f; 3.实例化对象中有pojo类型属性 二、IOC在Spring中的实现方式 1.获取bean的三种方式 1.1根据bean的id获取 1.2根据bean的类型获取&#xff08;最常用&#xff0c;因为在IOC容器中&#xff0c;一个类型的bean只…

APUE学习62章终端(一): 整体概览

1. 什么是终端 <Linux_UNIX系统编程手册下>的第62.1介绍了整体概览&#xff0c;但是说得比较模糊&#xff0c;什么是终端这个问题请参考下面的博客: https://www.cnblogs.com/changrunwei/p/15759664.html 它讲解了以下概念: 终端(UNIX和Linux把人和机器可以交互的接…

剑指offer47.礼物的最大价值

这道题挺简单&#xff0c;学过动态规划就会。如果要走到grid[i][j],那你的上一步必须是grid[i-1][j]或者grid[i][j-1],具体是grid[i-1][j]还是grid[i][j-1]&#xff0c;就看哪一步的价值最大&#xff0c;所以用一个与grid等大的dp数组来表示走到grid[i][j]的最大价值是dp[i][j]…

阿里用户序列建模MIMN

Practice on Long Sequential User Behavior Modeling for Click-Through Rate Prediction 摘要 对于序列建模&#xff0c;实践了机器学习算法与在线服务协同设计的CTR预测系统&#xff0c;理论上可以处理无限长的用户序列。 从服务系统的角度来看&#xff0c;通过设计一个单…

MIT 6.830数据库系统 -- lab five

MIT 6.830数据库系统 -- lab five 项目拉取引言搜索练习1 BTreeFile.findLeafPage() 插入练习2 Spliting Page 删除练习3 页再分配练习4 合并页 事务 项目拉取 原项目使用ant进行项目构建&#xff0c;我已经更改为Maven构建&#xff0c;大家直接拉取我改好后的项目即可: http…

选择器jQuery

诚信是你价格不菲的鞋子&#xff0c;踏遍千山万水&#xff0c;质量也应永恒不变。 jQuery选择器大全总结&#xff1a; jQuery选择器是一种用于在HTML文档中选择元素的强大工具。下面是一些常用的jQuery选择器的总结&#xff1a; 基本选择器&#xff1a; 元素选择器&#xff1a…

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

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

测试|测试用例设计常见面试题

测试|测试用例设计常见面试题 文章目录 测试|测试用例设计常见面试题1.怎么模拟弱网&#xff08;测试技巧&#xff09;2.怎么测试接口&#xff08;测试技巧&#xff09;3.怎么对冒泡排序测试&#xff08;代码类&#xff09;4.怎么对linux的zip命令进行测试&#xff08;软件类&a…

Linux: 设置qmake的Qt版本

Qt开发&#xff0c;qmake会对应一个Qt版本&#xff0c;有时候需要切换这个版本&#xff0c;例如把qmake从Qt5.12切换到Qt5.9, 怎么操作呢&#xff1f; 案例如下&#xff1a; 银河麒麟V10系统&#xff0c;下载安装了Qt5.9.8&#xff0c;但是检查qmake发现它使用的是5.12.8&…

《JeecgBoot系列》JeecgBoot(ant-design-vue)实现表单页面缓存(keep-alive)

JeecgBoot(ant-design-vue)实现表单页面缓存(keep-alive) 一、keep-alive介绍 keep-alive是vue的一个内置实例&#xff0c;通过这个属性可以缓存组件的v-node&#xff0c;可以实现页面缓存的功能。 keep-alive有三个属性&#xff1a; 1.include&#xff1a;记录了哪些组件可…

【Spring】聊聊Spring如何解决的循环依赖以及三级缓存

循环依赖是什么 在平时的面试中&#xff0c;只要问到Spring&#xff0c;那么大概率肯定会问什么是循环依赖&#xff0c;Sping是如何解决循环依赖的。以及三级缓存机制是什么。所以为了从根本上解决这个问题&#xff0c;本篇主要详细介绍一下循环依赖的问题。 Spring Bean初始…

IDEA格式化代码快捷键Ctrl+Alt+L失效解决

常见问题是网易云全局快捷键冲突 解决方法&#xff1a;取消下面的全局快捷键勾选

查看进程方式

目录 ps top uptime pstree ps 查看静态的进程统计信息 top 实时显示系统中各个进程的资源占用情况 第一行 top - 17:00:23 up 15 min, 1 user, load average: 1.05, 1.22, 0.98 17:00:23————当前时间 up 15 min————系统运行时间 1 user————当前登录用户数…

客户端实现阿里云OSS文件上传(分片上传,断点续传)

前言 阿里云OSS&#xff08;Object Storage Service&#xff09;是一种稳定、安全、高扩展性的云存储服务&#xff0c;它允许您以低成本、高可靠、高可用的方式存储和访问任意类型的数据。在实际应用中&#xff0c;文件上传是一个常见的功能需求。为了提高上传效率和文件完整性…