curses函数库简介及使用

curses函数库简介及使用

  • 导语
  • curses简介
  • 屏幕
    • 输出
    • 读取
    • 清除
    • 移动
    • 字符
  • 键盘
    • 键盘模式
    • 输入
  • 窗口
    • WINDOW
    • 常用函数
    • 屏幕刷新优化
  • 子窗口
  • keypad
  • 彩色显示
  • pad
  • 总结
  • 参考文献

导语

curses函数库主要用来实现对屏幕和光标的操作,它的功能定位处于简单文本行程序和完全图形化界面之间,在目前图形化界面已经蓬勃发展的现在可能显得有些过时,但是其中很多实现思想和操作仍然值得学习和借鉴,并且curses目前仍然是linux图形化编程的选择之一

curses简介

curses是一个函数库,它提供了许多对光标和终端屏幕的接口函数,在使用的时候必须包括对应的头文件函数声明和宏定义,并且用-lcurses进行定义,有些linux系统因为没有带相关的包,还需要安装类似libncurses5-dev的包

curses工作在屏幕、窗口和子窗口上,对于一个curses窗口,它一般被称为stdscr,与物理屏幕的尺寸一样,当然也可以创造一些别的尺寸小于当前屏幕的窗口,curses用两个ds来映射终端屏幕,stdscr和curscr,前者和stdout非常类似,是curses程序中的默认输出窗口,curscr和stdscr类似,对应的时当前屏幕的样子,需要注意的是,在程序调用refresh之前,输出到stdscr的内容不会显示在屏幕上,stdscr更像一个缓存,暂时存储一些改变

在调用refresh时,curses会比较stdscr和curscr(屏幕预状态和当前状态)之间的异同,之后根据差异刷新屏幕

一般来说,curses刷新逻辑屏幕的频率比刷新物理频率高,这很好理解,可以用计组中cache和内存之间的关系来类比,只有在程序执行的某些阶段,用户需要看到全部结果时,curses才会通过refresh计算出逻辑和物理之间对应的最佳途径,换句话说,curses只把最后的逻辑结果传递给物理屏幕

逻辑屏幕的布局是一个二维数组,每个位置不仅包含字符,还包含它的属性(例如粗体和下划线等),由于curses函数在使用的时候需要创建和删除一些临时ds,所以所有curses程序在开始使用前必须初始化,然后在结束使用之后恢复,通过initscr和endwin函数实现

屏幕

所有调用curses函数的程序必须以initscr和endwin结束,前者只能调用一次,成功则返回stdscr指针,否则返回错误信息,后者成功返回OK,失败返回ERR

输出

curses函数库有很多刷新屏幕的基本函数,书上很多,这里摘录并解释一些常用的函数,需要注意的是chtype是curses自己的字符类型,比标准char有更多位

int addch(const chtype char_to_add);
//在当前位置添加指定的字符
int printw(char *format);
//在光标位置输出,用法和printf一样
int refresh(void);
//刷新屏幕
int box(WINDOW *win_ptr, chtype vertical_char, chtype horizontal_char);
//围绕一个窗口画框,横竖用给定的字符
int insch(chtype char_to_insert);
//插入字符,将已有字符右移,准确来说是头插

读取

从屏幕上读取字符并不常用,但curses还是提供了对应的函数

chtype inch(void);
//返回光标当前位置字符和属性信息
int instr(char *string);
//返回字符串,写入string
int innstr(char *string,int number_of_characters);
//同上,但指定长度

清除

curses提供了四种清楚区域的方法,具体如下

int erase(void);
//在屏幕每个位置写上空白字符
int clear(void);
//彻底清除屏幕
int clrtobot(void);
//清除光标到屏幕尾
int clrtoeol(void);
//清除光标到当前行尾

移动

curses对光标的操作给的很少,只有两个函数,具体如下

int move(int new_y,int new_x);
//将逻辑光标移到指定地点,有外部整数LINES和COLUMNS
//并不会移动物理光标,需要移动则要用refresh
int leaveok(WINDOW *window_ptr,bool leave_flag);
//设置标志,控制屏幕刷新后物理光标的位置,0则和逻辑光标一样否则随机

字符

先前已经提到过,cureses中的每个字符是有属性的,这些属性是用宏来定义的,当需要修改时,直接使用这些宏作为对应参数给到函数即可,一些相关函数具体如下

int attron/attroff/attrset(chtype attribute);
//set是设置,on和off是开关
int standout/standend(void);
//反色显示

书上给出了一个例子,下面是代码和运行结果

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <curses.h>
int main()
{const char one[]=" First Witch ";const char two[]=" Second Witch ";initscr();move(5,15);attron(A_BOLD);//设置模式printw("%s","Bold test");//加粗输出attroff(A_BOLD);refresh();//刷新sleep(1);move(8,15);attron(A_STANDOUT);//设置模式printw("%s","test light");attroff(A_STANDOUT);//关闭反色refresh();sleep(1);move (10,10);//设置位置输出printw("%s","test sentence 1");move (11,13);printw("%s","test sentence 2");move(13,10);printw("%s","test sentence 3");move (14,23);printw("%s","test sentence 4");refresh();sleep(1);attron(A_DIM);int len=strlen(one);for(int i=len-1;i>=0;i--)//倒序插入{move(10,10);insch(one[i]);}len=strlen(two);for(int i=len-1;i>0;i--){move(13,10);insch(two[i]);}attroff(A_DIM);refresh();sleep(1);move(LINES-1,COLS-1);refresh();sleep(5);endwin();return 0;
}

可以看到加粗、反色和其他效果的字符串是什么样的

在这里插入图片描述

键盘

除了屏幕之外,curses还有针对键盘的一系列接口

键盘模式

在curses中有许多模式,例如预处理,默认输入等,在使用initscr时,输入模式处于预处理模式,只有在用户按下回车之后,输入的数据才会被传给程序(键盘的特殊字符被启用,组合键可产生信号),如果程序调用cbreak就可以将输入模式设置为cbreak模式,字符一经键入就被立刻传递给程序(特殊字符启用,一些简单字符直传)

一些相关的函数如下

int echo/noecho(void);
//启用/不启用回显
int cbreak/nocbreak(void);
//启用/不启用cbreak
int raw/noraw(void);
//启用/不启用特殊字符的处理

输入

一些读取键盘输入的函数具体如下

int getch(void);
//类似getchar
int getstr(char* string);
//类似gets
int getnstr(char* string,int number_of_characters);
//类似getnstr
int scanw(char* format,...);
//类似scanf

书上给出的一个具体的例子如下

#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <unistd.h>
int main()
{char name[256],pw[256];const char* rpw="1111";//真正的密码,用来检测initscr();//开模式move(5,10);printw("%s","login:");move(7,10);printw("%s","user name:");getstr(name);//拿用户名move(8,10);printw("%s","password:");cbreak();noecho();//关闭回显memset(pw,0,sizeof(pw));for(int i=0; i<256; i++){pw[i]=getch();if(pw[i]=='\n')break;move(8,20+i);addch('*');//把输入的对应位置插入*refresh();}echo();nocbreak();move(11,10);if(strncmp(rpw,pw,strlen(rpw)))printw("%s","wrong");elseprintw("%s","correct");refresh();sleep(2);endwin();return 0;
}

可以看到,这个例子实现了一个简单的密码隐藏和检测的功能,通过调用curses和设置光标的位置来实现

在这里插入图片描述

窗口

curses可以在物理屏幕上同时显示多个不同尺寸的窗口,而不仅仅是对单一窗口进行操控

WINDOW

stdscr是WINDOW的一个特例,是默认存在的,除此之外,在WINDOW中可以使用newwin和delwin来创建和销毁窗口,具体函数如下

WINDOW *newwin(int num_of_lines,int num_of_cols,int start_y,int start_x);
//创建一个新窗口,行数列数和开始位置
//新窗口完全独立于已存在窗口,并且覆盖它们的内容
int delwin(WINDOW *window_to_delete);
//删除,不能删除stdscr和curscr

常用函数

先前已经使用过一些屏幕上的函数,例如addch、printw等,但是这些函数还可以加上一些前缀变成通用函数,前缀w用于窗口,mv用于光标移动,mvw用于在窗口中移动光标,需要注意的是,当加上了对应的前缀时,函数的参数也会发生对应的变化,下面给出一些加上前缀后的具体函数

int mvwaddch(WINDOW* window_pointer, int y, int x, const chtype char);
int mvwprint(WINDOW *window_pointer, int y, int x, const chtype char);
int mvwin(WINDOW *window_to_move, int new_y, int new_x, int new_x);
int touchwin(WINDOW *window_ptr);
//通知curses窗口内容已改变,下次刷新必须重新绘制
int scrollok(WINDOW *window_ptr, bool scroll_flag);
//控制卷屏,传递给函数是布尔值则允许卷
int scroll(WINDOW *window_ptr);
//窗口内容上卷一行

书上给出的一个运行的例子,代码和部分运行结果如下

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <curses.h>
int main()
{WINDOW *nw_ptr,*pw_ptr;//新窗口和弹出创刊char ch='a';initscr();//开模式move(5,5);//移动光标printw("%s","Multiple windows");refresh();for(int i=0;i<255;i++)for(int j=0;j<255;j++){mvwaddch(stdscr,i,j,ch);//把数据插入整个屏幕ch=(++ch-'a')%26+'a';//循环小写字母}refresh();sleep(2);nw_ptr=newwin(10,20,5,5);//新窗口mvwprintw(nw_ptr,2,2,"%s","Hello World");mvwprintw(nw_ptr,5,2,"%s","1111111111111111111111111111111111111");wrefresh(nw_ptr);//刷新以显示sleep(2);ch='0';for(int i=0;i<255;i++)for(int j=0;j<255;j++){mvwaddch(stdscr,i,j,ch);ch=(++ch-'0')%10+'0';//循环数字}refresh();sleep(2);touchwin(nw_ptr);//通知curses窗口内容已变,调用刷新要重写窗口wrefresh(nw_ptr);sleep(2);pw_ptr=newwin(10,20,8,8);//创建新窗口box(pw_ptr,'|','-');//加上框mvwprintw(pw_ptr,5,2,"%s","Pop up Window!");wrefresh(pw_ptr);sleep(2);touchwin(nw_ptr);//显示wrefresh(nw_ptr);sleep(2);wclear(nw_ptr);//清屏wrefresh(nw_ptr);sleep(2);delwin(nw_ptr);touchwin(pw_ptr);wrefresh(pw_ptr);sleep(2);delwin(pw_ptr);touchwin(stdscr);refresh();sleep(2);endwin();return 0;
}

运行的时候可以看到,创建的新窗口覆盖了原有的背景窗口不分,然后新的两个窗口彼此相互覆盖,需要注意的是,如果要用curses刷新多个窗口,只能人为的管理这些窗口之间的先后关系

在这里插入图片描述

屏幕刷新优化

对屏幕的优化刷新需要一定技巧,当要更新的终端是通过慢速链路连接到主机时,就可能因为设备之间的不同步出问题,在慢速链路上,屏幕绘制的速度会非常慢,curses提供了相对应的手段,具体如下

int wnoutrefresh(WINDOW *window_ptr);
//决定把哪些字符发到屏幕上,但是只是缓存
int doupdate(void);
//把最后的更新结果输出到屏幕上
//如果想重新绘制多个窗口,可以为每个窗口调用wnoutrefresh,然后最后调用doupdate即可
//这是利用了缓存的思路

子窗口

子窗口和窗口的关系有点类似父进程和子进程,它的创建和删除的相关函数如下

WINDOW *subwin(WINDOW *parent, int num_of_lines,int num_of_cols, int start_y, int start_x);  
//类似newwin,子窗口和父窗口共享同一字符存储空间
int delwin(WINDOW *window_to_delete);

子窗口最主要的用途是,提供一种简洁方式卷动另一窗口的部分内容,在使用子窗口的时候,刷新屏幕必须先对父窗口调用touchwin,下面是书上给的一个例子代码和运行结果

#include <unistd.h>
#include <stdlib.h>
#include <curses.h>
#include <stdio.h>int main()
{WINDOW *sub;//窗口指针char ch='1';initscr();for(int i=0;i<255;i++)for(int j=0;j<255;j++){mvwaddch(stdscr,i,j,ch);//在对应位置插入字符ch=(++ch-'0')%9+'1';}sub=subwin(stdscr,10,20,10,10);//创建子窗口scrollok(sub,1);touchwin(stdscr);//刷新屏幕前调用父窗口refresh();sleep(1);werase(sub);//删除父窗口的对应区域mvwprintw(sub,2,0,"%s","scrolling");//输出wrefresh(sub);//刷新窗口sleep(1);for(int i=1;i<10;i++)//重新输出并滚动{wprintw(sub,"%s","wapping and scrolling");wrefresh(sub);sleep(1);}delwin(sub);touchwin(stdscr);refresh();sleep(1);endwin();return 0;
}

可以看到父窗口的一个小区域被清空,然后生成了一个子窗口,对子窗口进行输出并滚动

在这里插入图片描述

keypad

对于键盘上的按键,并不是所有的都可以通过ascall码来表示,比如insert、delete等,这些键在实际输入的时候往往是以escape字符开头的字符串序列,但这样就出现一个问题,系统需要识别单独按下escape键和以该键为首的字符串序列,curses提供了区分它们的实现,curses在启动时会关闭转义序列与逻辑键间的转换功能,通过keypad实现

int keypad(WINDOW *window_ptr, bool keypad_on);
//为了区分不同,curses会在检测到escape之后等待一小段时间,特别是启用keypad后

书上给出了一个keypad的实例,下面是代码和运行结果

#include <unistd.h>
#include <stdlib.h>
#include <curses.h>
#include <string.h>
#include <ctype.h>
int main()
{initscr();crmode();keypad(stdscr,1);//启用keypad模式noecho();//不回显clear();mvprintw(5,5,"q to quit");//打印字符move(7,5);//移动光标refresh();int key=getch();while(key!=ERR&&key!='q'){move(7,5);clrtoeol();//清除当前位置到行尾if(isalpha(key))//如果是字符printw("Key was %c", key);else{switch(key)//用特殊的宏来判断{case 27: printw("%s","Escape key");break;case KEY_END: printw("%s","END key");break;case KEY_BEG: printw("%s","BEGINNING key");break;case KEY_RIGHT: printw("%s","RIGHT key");break;case KEY_LEFT: printw("%s", "LEFT key");break;case KEY_UP: printw("%s","UP key");break;case KEY_DOWN: printw("%s","DOWN key");break;default: printw("Unmatched - %d",key);break;}}refresh();key=getch();}endwin();return 0;
}

可以看到程序可以识别所有的字符,以及一些设定好的特殊按键

在这里插入图片描述

彩色显示

curses对颜色的支持是通过组合来实现的,对于每个想使用的颜色组合,用户必须同时定义一个字符的前景和背景,相关函数具体如下

bool has_colors(void);
//判断终端是否支持彩色显示
int start_color(void);
//初始化颜色显示
int init_pair(short pair_number, short foreground, short background);
//初始化一个颜色组合,用pair_number来替代
int COLOR_PAIR(int pair_number);
//把颜色组合作为属性返回
int pair_content(short pair_number, short *foreground, short *background);
//获得已定义的颜色组合信息
int init_color(short color_number, short red, short green, short blue);
//把一个已有的颜色重新定义

书上给出的例子和运行结果如下

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <curses.h>
int main()
{initscr();if(!has_colors()){endwin();fprintf(stderr,"ERROR1\n");exit(1);}if(start_color()!=OK){endwin();fprintf(stderr,"ERROR2\n");exit(2);}        clear();mvprintw(5,5,"Colors types: %d, Color pairs: %d",COLORS,COLOR_PAIRS);refresh();init_pair(1,COLOR_RED,COLOR_BLACK);//初始化几个组合init_pair(2,COLOR_RED,COLOR_GREEN);init_pair(3,COLOR_GREEN,COLOR_RED);for(int i=1;i<=3;i++){attroff(A_BOLD);//关闭加粗attrset(COLOR_PAIR(i));//设置颜色组合mvprintw(5+i,5,"COLOR pair %d", i);attrset(COLOR_PAIR(i)|A_BOLD);//设置颜色组合+加粗mvprintw(5+i,25,"Bold color pair %d", i);refresh();sleep(3);}endwin();return 0;
}

可以看到以不同的颜色组合和加粗显示了字符串

在这里插入图片描述

pad

有时在使用curses时需要先建立一个逻辑屏幕,然后再把其部分内容投射到物理屏幕上,这个逻辑屏幕的尺寸可能会大于实际屏幕,curses提供了一个数据结构pad,它可以控制尺寸大于正常窗口的逻辑屏幕,具体函数如下

WINDOW *newpad(int number_of_lines, int number_of_columns);
int prefresh(WINDOW *pad_ptr, int pad_row, int pad_column,
int screen_row_min, int screen_col_min, int screen_row_max, int screen_col_max);
//将pad从指定坐标开始的区域写到屏幕上指定的显示区域,后两个坐标是显示范围

书上给出的例子和运行结果如下

#include <unistd.h>
#include <stdlib.h>
#include <curses.h>int main()
{WINDOW*pad;initscr();int lines=LINES+50,cols=COLS+50;pad=newpad(lines,cols);//创建新padchar ch='a';for(int i=0;i<lines;i++)for(int j=0;j<cols;j++){mvwaddch(pad,i,j,ch);ch=(++ch-'a')%26+'a';}prefresh(pad,5,7,2,2,9,9);//刷新显示sleep(1);prefresh(pad,LINES+5,COLS+7,5,5,21,19);//移动,再刷新显示一遍sleep(1);delwin(pad);endwin();return 0;
}

在这里插入图片描述

总结

可以看到,linux通过curses实现了对屏幕、键盘的读取,以及对子窗口,pad等的调用,为C语言实现可交互的应用程序提供了很好的实现方法和思路

参考文献

  1. 《Linux程序设计(第四版)》

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Prompt 模版解析:诗人角色的创意引导与实践

Prompt 模版解析&#xff1a;诗人角色的创意引导与实践 Prompt 模版作为一种结构化工具&#xff0c;旨在为特定角色——本例中的“诗人”——提供明确的指导和框架。这一模版详尽地描绘了诗人的职责、擅长的诗歌形式以及创作规则&#xff0c;使其能在自动化系统中更加精确地执…

[C#]C# winform部署yolov11-pose姿态估计onnx模型

【算法介绍】 在C# WinForms应用中部署YOLOv11-Pose姿态估计ONNX模型是一项具有挑战性的任务。YOLOv11-Pose结合了YOLO&#xff08;You Only Look Once&#xff09;的高效物体检测算法和Pose Estimation&#xff08;姿态估计&#xff09;专注于识别人体关键点的能力&#xff0…

【Nacos架构 原理】内核设计之Nacos寻址机制

文章目录 前提设计内部实现单机寻址文件寻址地址服务器寻址 前提 对于集群模式&#xff0c;集群内的每个Nacos成员都需要相互通信。因此这就带来一个问题&#xff0c;该以何种方式去管理集群内部的Nacos成员节点信息&#xff0c;即Nacos内部的寻址机制。 设计 要能够感知到节…

LeetCode讲解篇之695. 岛屿的最大面积

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历二维矩阵&#xff0c;如果当前格子的元素为1进行深度优先搜索&#xff0c;将搜索过的格子置为0&#xff0c;防止重复访问&#xff0c;然后对继续深度优先搜索上下左右中为1的格子 题解代码 func maxAr…

Redis实现每日签到(大数据量)

PHP语言使用Redis NoSQL服务器二进制数据类型实现大数据情况下签到功能 目录 问题 解决方式 封装签到类 功能调用 总结 问题 实现用户每日签到功能不难&#xff0c;但随着用户量上升之后&#xff0c;不论是存储还是判断对数据量来说都很麻烦&#xff1b;假如每天有100万用…

探索Spring Boot:实现“衣依”服装电商平台

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

通过 LLMs 自动探索量化投资策略

作者&#xff1a;老余捞鱼 原创不易&#xff0c;转载请标明出处及原作者。 写在前面的话&#xff1a; 本文提出了一个利用大型语言模型&#xff08;LLMs&#xff09;和多代理架构的新框架&#xff0c;用于量化股票投资和投资组合管理。该框架通过整合LLMs生成多样化的al…

【Unity】unity安卓打包参数(个人复习向/有不足之处欢迎指出/侵删)

1.Texture Compression 纹理压缩 设置发布后的纹理压缩格式 Use Player Settings:使用在播放器设置中设置的纹理压缩格式 ETC&#xff1a;使用ETC格式&#xff08;兼容&#xff09; ETC2&#xff1a;使用ETC2格式&#xff08;很多设备不支持&#xff09; ASTC&#xff1a;使用…

TypeScript:装饰器

一、简介 随着TypeScript和ES6里引入了类&#xff0c;在一些场景下我们需要额外的特性来支持标注或修改类及其成员。 装饰器&#xff08;Decorators&#xff09;为我们在类的声明及成员上通过元编程语法添加标注提供了一种方式。 Javascript里的装饰器目前处在 建议征集的第二阶…

Hadoop大数据入门——Hive-SQL语法大全

Hive SQL 语法大全 基于语法描述说明 CREATE DATABASE [IF NOT EXISTS] db_name [LOCATION] path; SELECT expr, ... FROM tbl ORDER BY col_name [ASC | DESC] (A | B | C)如上语法&#xff0c;在语法描述中出现&#xff1a; []&#xff0c;表示可选&#xff0c;如上[LOCATI…

大模型项目如何判断用RAG还是微调

大模型项目如何判断用RAG还是微调 在大模型项目中&#xff0c;选择使用检索增强生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;还是微调&#xff08;Fine-Tuning&#xff09;取决于多个因素&#xff0c;包括项目的具体需求、数据的可用性、性能要求、成本和…

浅谈汽车智能座舱如何实现多通道音频

一、引言 随着汽车智能座舱的功能迭代发展&#xff0c;传统的 4 通道、6 通道、8 通道等音响系统难以在满足驾驶场景的需求&#xff0c;未来对于智能座舱音频质量和通道数会越来越高。接下来本文将浅析目前智能座舱如何实现音频功放&#xff0c;以及如何实现多路音频功放方案。…

CSS基础-常见属性(二)

6、CSS三大特性 6.1 层叠性 如果样式发生冲突&#xff0c;则按照优先级进行覆盖。 6.2 继承性 元素自动继承其父元素、祖先元素所设置的某些元素&#xff0c;优先继承较近的元素。 6.3 优先级 6.3.1 简单分级 1、内联样式2、ID选择器3、类选择器/属性选择器4、标签名选择器/…

环境对于写作有何影响?

如果你是有灵性、热爱文学创作的人&#xff0c;多半就会喜欢安静的生活环境。因为你会感受到唯有在这样的环境里更才能够沉下心来思考创作的路径。而且此时的你&#xff0c;显得头脑清醒、思维活跃而自由&#xff0c;因之文思泉涌。 网络图&#xff1a;宁静的书房 反之&#x…

【数据结构】什么是平衡二叉搜索树(AVL Tree)?

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 &#x1f4cc;AVL树的概念 &#x1f4cc;AVL树的操作 &#x1f38f;AVL树的插入操作 ↩️右单旋 ↩️↪️右左双旋 ↪️↩️左右双旋 ↪️左单旋 &#x1f38f;AVL树的删…

SpringBoot驱动的明星周边产品电商解决方案

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

什么是 ARP 欺骗和缓存中毒攻击?

如果您熟悉蒙面歌王&#xff0c;您就会明白蒙面歌王的概念&#xff1a;有人伪装成别人。然后&#xff0c;当面具掉下来时&#xff0c;您会大吃一惊&#xff0c;知道了这位名人是谁。类似的事情也发生在 ARP 欺骗攻击中&#xff0c;只是令人惊讶的是&#xff0c;威胁行为者利用他…

网站集群批量管理-密钥认证与Ansible模块

一、集群批量管理-密钥认证 1、概述 管理更加轻松&#xff1a;两个节点,通过密钥形式进行访问,不需要输入密码,仅支持单向. 服务要求(应用场景)&#xff1a; 一些服务在使用前要求我们做秘钥认证.手动写批量管理脚本. 名字: 密钥认证,免密码登录,双机互信. 2、原理 税钥对…

PyGWalker:让你的Pandas数据可视化更简单,快速创建数据可视化网站

1、PyGWalker应用: 在数据分析的过程中,数据的探索和可视化是至关重要的环节,如何高效地将分析结果展示给团队、客户,甚至是公众,是很多数据分析师和开发者面临的挑战,接下来介绍的两大工具组合——PyGWalker与Streamlit,可以帮助用户轻松解决这个问题,即使没有复杂的代…

VMware ESXi 7.0U3q macOS Unlocker OEM BIOS 2.7 Dell HPE 联想定制版 9 月更新发布

VMware ESXi 7.0U3q macOS Unlocker & OEM BIOS 2.7 Dell HPE 联想定制版 9 月更新发布 VMware ESXi 7.0U3q macOS Unlocker & OEM BIOS 2.7 标准版和厂商定制版 ESXi 7.0U3 标准版&#xff0c;Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur (浪潮)、Cisco (思科)…