BIO、NIO、AIO、Netty从简单理解到使用
Java编程中BIO、NIO、AIO是三种不同的I/O(输入/输出)模型,它们代表了不同的I/O处理方式。
Netty就是基于Java的NIO(New Input/Output)类库编写的一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。
先来了解一下基本的三种基本的io模型:
BIO(Blocking I/O,阻塞I/O)
定义:BIO是Java最传统的I/O模型,基于流的同步阻塞I/O操作。每个连接都会占用一个线程,当进行I/O操作时,线程会被阻塞,直到操作完成。
特点:
同步阻塞:每个I/O操作都会阻塞当前线程,直到操作完成。
线程占用:每个连接需要一个独立的线程,线程资源消耗较大。
实现简单:代码实现相对简单,易于理解和编写。
作用:适用于连接数较少且固定的架构,如传统的C/S架构。由于其实现简单、编程直观,因此在一些简单的网络编程场景中仍然被使用。
创建客户端和服务端演示数据接收与传输。
//服务端
public static void main(String[] args) {try (ServerSocket serverSocket = new ServerSocket(9999)) {while (true) {Socket socket = serverSocket.accept(); // 持续监听新连接new Thread(() -> { // 为每个客户端创建独立线程try (BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {String line;while ((line = reader.readLine()) != null) {System.out.println("客户端[" + socket.getPort() + "] 消息: " + line);}} catch (IOException e) {e.printStackTrace();}}).start();}} catch (IOException e) {e.printStackTrace();}}//客户端
public static void main(String[] args) {System.out.println("客户端启动...");try {//创建套接字Socket socket = new Socket("127.0.0.1", 9999);//获取输出流发送消息PrintStream ps = new PrintStream(socket.getOutputStream());Scanner sc = new Scanner(System.in);while (true){System.out.println("请输入信息:");ps.println(sc.nextLine());ps.flush();}} catch (IOException e) {throw new RuntimeException(e);}}
NIO(Non-blocking I/O,非阻塞I/O)
定义:NIO是Java 1.4引入的新I/O API,基于通道(Channel)和缓冲区(Buffer)的非阻塞I/O操作。
特点:
非阻塞:I/O操作不会阻塞线程,线程可以在等待数据时执行其他任务。
多路复用:通过Selector可以管理多个Channel,提高了资源利用率。
高性能:适用于高并发场景,减少线程开销和上下文切换。
核心组件:
缓冲区(Buffer):用于存储数据的固定大小的内存区域,提供了多种类型的缓冲区,如ByteBuffer、CharBuffer等。
通道(Channel):用于数据读写的通道,支持非阻塞模式,与缓冲区配合使用。
选择器(Selector):允许单个线程同时处理多个通道的I/O事件。
作用:适用于连接数较多且连接较短的架构,如高并发的服务器端应用。NIO提供了更高效、更灵活的I/O操作方式,显著提高了系统的并发性能和吞吐量。
//服务端public static void main(String[] args) throws Exception {//创建连接通道,ServerSocketChannel 绑定端口,监听新的客户端连接请求。它本身不处理任何数据传输。ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 设置通道为非阻塞模式serverSocketChannel.configureBlocking(false);//绑定端口serverSocketChannel.bind(new InetSocketAddress(9999));//创建 Selector 并注册 ACCEPT 事件Selector selector = Selector.open();serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);System.out.println("NIO 服务端启动...");//阻塞等待事件发生while (selector.select()>0){//获取到所有事件Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();//遍历所有事件while (iterator.hasNext()){SelectionKey key = iterator.next();//检查是否有新的连接请求if(key.isAcceptable()){//为每一个创建新的通道SocketChannel clientChannel = serverSocketChannel.accept();clientChannel.configureBlocking(false);clientChannel.register(selector,SelectionKey.OP_READ);}else if(key.isReadable()){//处理读数据SocketChannel channel = (SocketChannel)key.channel();ByteBuffer byteBuffer = ByteBuffer.allocate(1024);int bytesRead = 0;while ((bytesRead = channel.read(byteBuffer)) > 0){byteBuffer.flip();String message = new String(byteBuffer.array(),0,bytesRead);System.out.println("接收客户端信息:"+message);byteBuffer.clear();//回写数据给客户端ByteBuffer response = ByteBuffer.wrap(("ECHO: " + message).getBytes());channel.write(response);}}iterator.remove();}}}//客户端
public static void main(String[] args) throws Exception {// 1. 创建 SocketChannel 并连接服务器SocketChannel socketChannel = SocketChannel.open();socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));socketChannel.configureBlocking(false); // 非阻塞模式System.out.println("NIO 客户端已连接");//接收线程new Thread(() -> {ByteBuffer buffer = ByteBuffer.allocate(1024);while (true) {try {int bytesRead = socketChannel.read(buffer);if (bytesRead > 0) {buffer.flip();byte[] data = new byte[buffer.remaining()];buffer.get(data);System.out.println("收到服务端响应: " + new String(data));buffer.clear();}} catch (IOException e) {System.out.println("连接已断开");break;}}}).start();//发送消息ByteBuffer byteBuffer = ByteBuffer.allocate(1024);Scanner sc = new Scanner(System.in);while (true){System.out.println("请输入信息:");String msg = sc.nextLine();byteBuffer.put(("AA:"+msg).getBytes(StandardCharsets.UTF_8));byteBuffer.flip();socketChannel.write(byteBuffer);byteBuffer.clear();}}
AIO(Asynchronous I/O,异步I/O)
定义:AIO是Java 7引入的异步I/O API,基于异步通道(AsynchronousChannel)和异步回调机制。
特点:
异步非阻塞:I/O操作是异步的,通过回调处理结果,不阻塞线程。
回调机制:通过回调函数处理I/O操作结果,提高了程序的灵活性。
高性能:适用于高并发、高吞吐量的场景。
工作方式:
程序发起一个异步I/O请求,并提供一个回调函数。
程序无需等待I/O操作完成,而是立即返回,继续执行其他任务。
当I/O操作完成后,系统会调用之前提供的回调函数,传递结果或状态信息。
作用:适用于连接数较多且连接时间较长的架构,如高并发的服务器端应用。AIO提供了真正的异步I/O操作方式,进一步提高了系统的并发性能和吞吐量。
Netty
先了解一下netty出现的原因,是干嘛用的?
- Netty出现的原因:
Java NIO的复杂性:
Java NIO虽然提供了非阻塞IO的能力,但其API设计较为底层,使用起来比较复杂。开发者需要处理大量的细节,如选择器的管理、缓冲区的操作等,这增加了开发的难度和出错的风险。
性能瓶颈:
在高并发场景下,直接使用Java NIO进行网络编程可能会遇到性能瓶颈。例如,选择器的实现和多线程管理的复杂性可能导致性能下降。
缺乏高级功能:
Java NIO仅提供了基础的非阻塞IO机制,缺乏一些高级功能,如协议编解码、连接管理等。这些功能在开发网络应用时非常重要,但实现起来却相对复杂。
- Netty的具体用途是什么?
简化网络编程:
Netty封装了Java NIO的复杂性,提供了一套简洁易用的API。开发者可以使用这些API快速构建网络应用,而无需关注底层的细节。
提高性能:
Netty采用了异步非阻塞IO模型,并支持零拷贝等技术,可以在保证高性能的同时,减少CPU和内存资源的消耗。这使得Netty在高并发场景下表现尤为出色。
支持多种协议:
Netty内置了对多种协议的支持,如TCP、UDP、HTTP、WebSocket等。开发者可以轻松地使用这些协议构建网络应用,而无需自己实现协议编解码等复杂功能。
灵活的扩展性:
Netty提供了丰富的扩展点,如ChannelHandler、Codec等。开发者可以通过实现这些接口来扩展Netty的功能,以满足特定的业务需求。
广泛的应用场景:
Netty经过广泛的使用和验证,具有高稳定性和可靠性,适用于各种网络应用场景,如分布式系统、微服务架构中的通信组件、实时通讯系统、游戏服务器等。
它提供了丰富的错误处理和恢复机制,能够有效地处理网络通信中的各种异常情况。
netty核心优势:
异步事件驱动、零拷贝、内存池、高度可定制。
- 核心组件
先大概了解一下 Reactor 模型(单线程、多线程、主从多线程)。
因为Reactor 模式是 Netty 高性能和高并发能力的核心设计基础。Netty 的线程模型、事件驱动机制和异步非阻塞 I/O 都深度依赖 Reactor 模式。
Reactor 模式是一种 事件驱动的设计模式,用于处理高并发的 I/O 请求。其核心思想是 用一个或多个线程监听事件(如连接、读写请求),并将事件分发给对应的处理器异步处理,避免线程阻塞和资源浪费。
Reactor模型的核心组件
事件源(Event Source):指任何可以产生I/O事件的对象,例如网络连接、文件、设备等。
事件循环(Event Loop):Reactor模型的核心,负责监控所有事件源的状态,并在有事件发生时将其分发给相应的处理程序(即回调函数)。
事件处理器(Event Handler):处理特定事件的代码模块,通常实现为回调函数或方法。针对特定的事件源,每一个事件源通常都有一个相应的处理器,用于处理该事件源的I/O事件。
多路复用器(Demultiplexer):用于监视多个事件源并将发生的事件通知给Reactor。常见的实现包括Java的Selector、Linux的epoll等。
Reactor模型的实现方式
单Reactor单线程模型:所有操作(连接、读写)由一个线程完成。设计简单,但在高并发场景下容易成为性能瓶颈。
单Reactor多线程模型:Reactor线程负责监听和分发事件,而事件的处理则交给线程池中的工作线程完成。这种方式能够充分利用多核CPU的处理能力,但在高并发场景下,Reactor线程可能成为性能瓶颈。
主从Reactor多线程模型(Netty 默认模型-高并发):也称为多Reactor多线程模型。主Reactor线程负责监听和分发连接事件,当有新的连接到来时,将其分发给从Reactor线程处理。从Reactor线程负责监听和分发读写事件,并交给线程池中的工作线程处理。这种方式能够进一步提高系统的并发处理能力和可扩展性。
写个netty服务端示例看一下:
// 1. 创建主 Reactor(处理连接)管理一组 EventLoop,每个线程绑定一个 EventLoop(事件循环线程)
EventLoopGroup bossGroup = new NioEventLoopGroup(1); // 主线程组(通常 1 个线程)
// 2. 创建子 Reactor(处理 I/O)
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 子线程组(默认 CPU 核数 × 2)//Reactor 模式配置入口 绑定主/子线程组、设置 Channel 类型
ServerBootstrap server = new ServerBootstrap();
server.group(bossGroup, workerGroup) // 绑定主从线程组.channel(NioServerSocketChannel.class) // 设置 Channel 类型(NIO)代表一个 Socket 连接或监听端口.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) {ch.pipeline().addLast(new ServerHandler()); // 添加业务处理器,这里需要自己实现}});// 3. 绑定端口并启动服务
ChannelFuture future = server.bind(8080).sync();
//等待服务器通道关闭
future.channel().closeFuture().sync();
//关闭通道
finally {workerGroup.shutdownGracefully();bossGroup.shutdownGracefully();}//业务处理器
public class ServerHandler extends ChannelInboundHandlerAdapter {@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {System.out.println("客户端连接成功...");}}
- 组件说明:
Channel:
在Netty中,Channel是一个核心概念,Channel提供了数据的读取和写入操作,以及与远程端点进行通信的能力。
通过Channel可以获取到很多信息,比如:本地地址、远程地址、Channel的EventLoop、Channel的Pipeline等。
Channel 生命周期:
channelRegistered (初始化操作)→ channelActive (连接)→ channelRead(数据接收) → channelInactive(断开)→ channelUnregistered(注销)
Selector:
Selector是Java NIO(New Input/Output)中的一个核心组件,用于监控多个Channel(通道)的状态,例如连接、读、写等事件。在netty中Selector被封装在NioEventLoop中,当Channel注册到Selector并指定感兴趣的事件类型(如连接、读、写等)后,会返回一个SelectionKey,用于表示Selector与Channel之间的关联关系。Selector会不断地轮询其注册的Channel,如果有事件发生,Selector会将相应的SelectionKey放入就绪事件集合中。事件循环线程会从就绪事件集合中取出SelectionKey,并根据事件类型调用相应的ChannelHandler进行处理。处理完成后,事件循环线程会将Channel放回到Selector中,继续等待下一次事件的发生。
EventLoopGroup:
管理一组 EventLoop,通常分为 bossGroup(处理连接)和 workerGroup(处理 I/O)。
配置线程数:new NioEventLoopGroup(4) 表示 4 个线程。
ServerBootstrap:
用于启动服务器端的引导类,配置服务器参数和处理器链配置、启动服务器、关闭服务器。
- 配置服务器参数:
线程模型:ServerBootstrap允许您配置两个主要的线程组:bossGroup和workerGroup。
bossGroup用于处理客户端的连接请求,而workerGroup用于处理已连接的客户端的I/O操作。
通道类型:通过channel方法,您可以指定服务器使用的通道类型。对于NIO传输,通常使用NioServerSocketChannel。
通道选项:使用option方法可以设置服务器通道的选项,如SO_BACKLOG(TCP连接请求的最大队列长度)和SO_REUSEADDR(允许地址重用)。
子通道选项:childOption方法用于设置已连接客户端的通道选项,如SO_KEEPALIVE(保持连接活动状态)。
Option:可以应用于Channel或Bootstrap上。
ChannelOption:专门用于配置Channel的参数。
- 处理器链配置:
父处理器:通过handler方法,您可以设置处理服务器通道I/O事件的处理器。这通常用于处理连接请求。
子处理器:childHandler方法用于设置处理已连接客户端I/O事件的处理器。这是开发者编写业务逻辑处理代码的地方,通常通过添加一系列的ChannelHandler来实现。
ChannelHandler
ChannelHandler是ChannelPipeline中的基本处理单元,负责处理或拦截入站和出站事件。每个ChannelHandler都有一个关联的ChannelHandlerContext,通过它可以方便地与其他组件进行交互。ChannelPipeline则是ChannelHandler的容器,负责ChannelHandler的管理和事件拦截。
pipeline、ChannelPipeline
Pipeline是ChannelPipeline的简称。ChannelPipeline用于处理网络事件和数据的流动。负责将一系列的处理逻辑(称为ChannelHandler)串联起来,形成一个处理链,对网络事件进行拦截和处理。
事件处理:ChannelPipeline负责处理入站(Inbound)和出站(Outbound)事件,如数据读取、数据写入、连接建立、连接断开等。
拦截器链:ChannelPipeline内部维护了一个拦截器链(或称为处理器链),每个拦截器(即ChannelHandler)都可以对事件进行处理或拦截。
动态性:ChannelPipeline允许在运行时动态地添加、删除或替换拦截器,从而灵活地扩展和定制网络处理逻辑。
-
启动服务器:
配置完成后,通过调用bind方法并传入服务器的端口号,ServerBootstrap将启动服务器并绑定到指定的端口。
bind方法返回一个ChannelFuture对象,您可以使用sync方法等待服务器启动完成。
ChannelFuture是Netty框架中特有的接口,继承自Java的Future接口。在Netty中,所有的I/O操作都是异步的,ChannelFuture用于在操作完成时通知应用程序,以便应用程序可以执行某些操作或检索操作的结果。 -
关闭:
当服务器需要关闭时,可以调用ChannelFuture对象的channel().closeFuture().sync()方法,等待服务器通道关闭。
最后,调用bossGroup和workerGroup的shutdownGracefully方法,以优雅地断开连接并关闭线程组。
ChannelHandlerContext:
ChannelHandlerContext封装了Channel和ChannelPipeline,使得ChannelHandler可以方便地访问和操作ChannelPipeline和Channel。
ChannelHandlerContext提供了许多方法,用于操作和传播事件,如写入数据、刷新数据、触发读事件等。
ChannelHandlerContext允许ChannelHandler将事件传递给ChannelPipeline中的下一个处理器。例如,当一个入站事件(如数据读取)发生时,ChannelHandlerContext可以调用fireChannelRead方法,将事件传递给下一个入站处理器。
相关文章:
BIO、NIO、AIO、Netty从简单理解到使用
Java编程中BIO、NIO、AIO是三种不同的I/O(输入/输出)模型,它们代表了不同的I/O处理方式。 Netty就是基于Java的NIO(New Input/Output)类库编写的一个高性能、异步事件驱动的网络应用程序框架,用于快速开发可…...
计算机毕业设计SpringBoot+Vue.js工厂车间管理系统源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
一、图形图像的基本概念
文章目录 一、分辨率概念二、图形图像的区别三、位图和矢量图的区别 一、分辨率概念 图形显示计数中的分辨率概念有三种,即屏幕分辨率、显示分辨率和显卡分辨率。它们既有区别又有着密切的联系,对图形显示的处理有极大的影响。 1.屏幕分辨率 显示器分辨…...
前端跨域问题初探:理解跨域及其解决方案概览
在当今的Web开发中,跨域问题是一个常见且棘手的挑战 随着前端技术的不断进步,越来越多的应用需要从不同的域名、协议或端口获取资源 然而,浏览器的同源策略(Same-Origin Policy)限制了这种跨域请求,以确保…...
SQL分组问题
下列为电商公司用户访问时间数据 统计某个用户连续的访问记录,如果时间间隔小于60s,就分为一组 id ts 1001 17523641234 1001 17523641256 1002 17523641278 1001 17523641334 1002 17523641434 1001 17523641534 1001 17523641544 1002 17523…...
Oracle 数据库基础入门(二):深入理解表的约束
在 Oracle 数据库的学习进程中,表的约束是构建健壮、准确且高效数据库的关键要素。约束如同数据库的 “规则守护者”,它通过对数据的限制,确保了数据的完整性和一致性,就如同交通规则保障道路上车辆行驶的有序性一样。对于 Java 全…...
DeepSeek掘金——DeepSeek-R1驱动的房地产AI代理
DeepSeek掘金——DeepSeek-R1驱动的房地产AI代理 本文探讨如何使用 Smolagents 和 DeepSeek-R1 构建房地产代理,并利用工具进行网页抓取和数据导出。 AI 代理对于自动化复杂的推理任务至关重要。Smolagents 是由 Hugging Face 开发的轻量级 AI 代理框架,允许将大型语言模型 …...
WebP2P技术在嵌入式设备中的应用:EasyRTC音视频通话SDK如何实现高效通信?
在数字化时代,实时通信技术(RTC)与人工智能(AI)的融合正在重塑各个行业的交互方式。从在线教育到远程医疗,从社交娱乐到企业协作,RTC的应用场景不断拓展。然而,传统的RTC解决方案往往…...
【零基础到精通Java合集】第三集:流程控制与数组
针对**“流程控制与数组”**的15分钟课程内容设计,聚焦代码逻辑设计与数据结构基础: 课程标题:流程控制与数组(15分钟) 目标:掌握分支/循环语法与数组操作,能编写条件判断与数据遍历程序 一、课程内容与时间分配 0-2分钟 课程目标与逻辑导图 明确学习目标:分支结构、…...
VsCode + EIDE + OpenOCD + STM32(野火DAP) 开发环境配置
VsCode EIDE OpenOCD STM32(野火DAP) 开发环境配置 接受了新时代编辑器的我,实在受不了Keil的上古编辑页面,周树人说过:由奢入俭难,下面我们一起折腾一下开源软件Vscode, 用以开发51和STM32,有错误之处&…...
【vue-echarts】——01.认识echarts
文章目录 前言一、echarts二、使用步骤1.vue cli创建项目并安装第三方模块echarts2.显示图表总结前言 定制的数据可视化图表。ECharts最初由百度团队开源,并于2018年初捐赠给Apache基金会,成为ASF孵化级项目。2021年1月26日晚,Apache基金会官方宣布ECharts项目正式毕业。 一…...
【http://noi.openjudge.cn/】4.3算法之图论——1538:Gopher II
[【http://noi.openjudge.cn/】4.3算法之图论——1538:Gopher II] 题目 查看提交统计提问 总时间限制: 2000ms 内存限制: 65536kB 描述 The gopher family, having averted the canine threat, must face a new predator. The are n gophers and m gopher holes, each at di…...
Linux常见操作命令
Linux系统拥有丰富的命令行工具,通过这些命令可以高效地完成各种系统管理和日常操作任务。以下是一些常见的Linux操作命令: 文件和目录操作: - 创建目录:使用 mkdir 命令,例如 mkdir test 可以创建名为 test 的目录。如…...
Linux下测试Wifi性能——2.Linux下wifi指令
一、前言 相关知识大家看前一章节 Linux下测试Wifi性能——1.Wifi相关知识-CSDN博客 二、指令 1.查找可用网卡 iw dev 其中 接口名称(Interface) p2p0 和 wlan0 都是无线接口(网卡)的名称。 wlan0 是常见的无线局域网接口名…...
(十 九)趣学设计模式 之 中介者模式!
目录 一、 啥是中介者模式?二、 为什么要用中介者模式?三、 中介者模式的实现方式四、 中介者模式的优缺点五、 中介者模式的应用场景六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,…...
Leetcode 54: 螺旋矩阵
Leetcode 54: 螺旋矩阵 是一道经典的矩阵遍历模拟题目,要求我们以螺旋顺序遍历一个二维数组。这个问题在面试中非常经典,考察模拟、数组操作以及逻辑清晰度。掌握本题的高效解法可以迅速给面试官留下好印象。 适合面试的解法:边界法ÿ…...
abseil-cpp:环境搭建
参考: https://abseil.io/docs/cpp/quickstart-cmake abseil-cpp.git/dd4c89b abseil-cpp.git/20240722.1 1. clone代码仓库、编译 git clone https://github.com/abseil/abseil-cpp.git /app/abseil-cpp/ #/app/abseil-cpp/.git/config git checkout 20240722.1git rev-pa…...
Centos7部署k8s(单master节点安装)
单master节点部署k8s集群(Centos) 一、安装前准备 1、修改主机名 按照资源准备修改即可 # master01 hostnamectl set-hostname master01 ; bash # node1 hostnamectl set-hostname node1 ; bash # node2 hostnamectl set-hostname node2 ; bash2、修改hosts文件 以下命令所…...
RPA 职业前景:个人职场发展的 “新机遇”
1. RPA职业定义与范畴 1.1 RPA核心概念 机器人流程自动化(RPA)是一种通过软件机器人模拟人类操作,自动执行重复性、规则性任务的技术。RPA的核心在于其能够高效、准确地处理大量数据和流程,减少人工干预,从而提高工作…...
详解DeepSeek模型底层原理及和ChatGPT区别点
一、DeepSeek大模型原理 架构基础 DeepSeek基于Transformer架构,Transformer架构主要由编码器和解码器组成,在自然语言处理任务中,通常使用的是Transformer的解码器部分。它的核心是自注意力机制(Self - Attention),这个机制允许模型在处理输入序列时,关注序列中不同位…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
C++ 基础特性深度解析
目录 引言 一、命名空间(namespace) C 中的命名空间 与 C 语言的对比 二、缺省参数 C 中的缺省参数 与 C 语言的对比 三、引用(reference) C 中的引用 与 C 语言的对比 四、inline(内联函数…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...
wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...
沙箱虚拟化技术虚拟机容器之间的关系详解
问题 沙箱、虚拟化、容器三者分开一一介绍的话我知道他们各自都是什么东西,但是如果把三者放在一起,它们之间到底什么关系?又有什么联系呢?我不是很明白!!! 就比如说: 沙箱&#…...
node.js的初步学习
那什么是node.js呢? 和JavaScript又是什么关系呢? node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说, 需要在node.js的环境上进行当JavaScript作为前端开发语言来说,需要在浏览器的环境上进行 Node.js 可…...
