当前位置: 首页 > news >正文

TCP实现多线程远程命令执行

1.上一篇篇代码改进

bind的绑定第一个是对象,其余的都是参数,传给一个类需要this指针,所以有&r

错误地方是智能指针的参数要加&,thread.name()要删除 

2.介绍需要用到函数

popen函数

FILE *popen(const char *command, const char *type);

  • command:这是一个指向以空字符结尾的字符串的指针,该字符串包含要执行的命令。这个命令可以是任何可以在命令行中运行的命令。

  • type:这是一个字符串,指定管道的方向。它只能是以下两种模式之一:

    • "r":表示从子进程的输出中读取数据。

    • "w":表示向子进程的输入中写入数据。

2. 参数解释

  • cmd.c_str()cmd 是一个 std::string 对象,cmd.c_str() 是一个成员函数,它返回一个指向以空字符结尾的字符串的指针。这个指针可以直接传递给 popen 函数。

  • "r":表示从子进程的输出中读取数据。这意味着子进程的标准输出会被重定向到父进程的文件流中。

3. 返回值

  • popen 函数返回一个指向 FILE 类型的指针,这个指针可以用于后续的 I/O 操作(如 freadfwritefgets 等)。

  • 如果 popen 调用失败,返回值为 NULL

listen函数

int listen(int sockfd, int backlog);

参数

  • sockfd:已经绑定到本地地址的套接字描述符。

  • backlog:未完成连接队列的最大长度。这个值表示操作系统可以为该套接字维护的未完成连接的最大数量。

返回值

  • 成功时返回 0

  • 失败时返回 -1,并设置 errno 以指示错误原因。

作用

  • 将套接字从主动模式转换为被动模式,使其能够接收客户端的连接请求。

  • 设置未完成连接队列的最大长度,当队列已满时,新的连接请求将被拒绝

connect函数

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

参数

  • sockfd:客户端的套接字描述符。

  • addr:指向 struct sockaddr 的指针,包含服务器的地址信息。

  • addrlenaddr 的长度。

返回值

  • 成功时返回 0

  • 失败时返回 -1,并设置 errno 以指示错误原因。

作用

  • 将客户端的套接字连接到指定的服务器地址。

  • 如果连接成功,套接字将进入已连接状态,可以进行数据传输。

accept函数

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

 

参数

  • sockfd:监听套接字描述符。

  • addr:指向 struct sockaddr 的指针,用于存储客户端的地址信息。如果不需要获取客户端的地址信息,可以将其设置为 NULL

  • addrlen:指向 socklen_t 的指针,表示 addr 的长度。在调用 accept 之前,需要将其设置为 addr 的大小。调用后,addrlen 会被设置为实际存储在 addr 中的地址的长度。

返回值

  • 成功时返回一个新的套接字描述符,用于与客户端通信。

  • 失败时返回 -1,并设置 errno 以指示错误原因。

作用

  • 从监听队列中取出一个已完成的连接请求,并为该连接创建一个新的套接字。

  • 新的套接字描述符可以用于与客户端进行数据传输。

fgets函数

char *fgets(char *str, int size, FILE *stream);

参数

  • str:指向字符数组的指针,用于存储读取到的字符串。

  • size:指定字符数组的最大长度。fgets 会读取最多 size - 1 个字符,以确保在数组末尾添加空字符 \0

  • stream:文件流指针,指向要读取的文件。

返回值

  • 如果成功读取到一行数据,返回值是 str,即指向存储读取到的字符串的指针。

  • 如果到达文件末尾或发生错误,返回值为 NULL

3.TcpServer文件

1.Init函数实现

开始在栈区上创建一个套接字,接着创建InetAddr类的对象,把端口号传过去,会构造一个sockaddr_in的结构体,并初始化这个结构体,接着把栈区上的套接字作为参数执行bind函数,进入到内核态中绑定,使套接字有效,因为是tcp通信就需要相互连接,就需要listen函数,把状态变为监听。

listen,connect和accept:

假设你正在经营一家餐厅,`listen`、`connect` 和 `accept` 的过程可以类比为以下场景:

1. **`listen`**:
   - 你告诉员工:“开始接听预订电话。”
   - 这时,你的电话系统(套接字)处于监听状态,准备接收客户的预订请求。

2. **`connect`**:
   - 客户拨打你的预订电话,尝试与你联系。
   - 这就好比客户端调用 `connect`,向服务器发起连接请求。

3. **`accept`**:
   - 你的员工接听电话,并记录下客户的预订信息。
   - 这就好比服务器调用 `accept`,接受客户端的连接请求,并为该客户分配一个新的资源

 void Init(){_listensockfd=socket(AF_INET,SOCK_STREAM,0);if(_listensockfd<0){LOG(LogLevel::FATAL)<<"socket error";exit(SOCKET_ERR);}LOG(LogLevel::INFO)<<"socket success:"<<_listensockfd;InetAddr local(_port);int n=bind(_listensockfd,local.NetAddrPtr(),local.NetAddrLen());if(n<0){LOG(LogLevel::FATAL)<<"bind error";exit(BIND_ERR);}LOG(LogLevel::INFO)<<"bind success:"<<_listensockfd;n=listen(_listensockfd,backlog);if(n<0){LOG(LogLevel::FATAL)<<"listen error";exit(LISTEN_ERR);}LOG(LogLevel::INFO)<<"listen sucess:"<<_listensockfd;}InetAddr(uint16_t port):_port(port),_ip(){memset(&_addr,0,sizeof(_addr));_addr.sin_family=AF_INET;_addr.sin_addr.s_addr=INADDR_ANY;_addr.sin_port=htons(_port);}

2.service函数实现

创建一个缓冲区buffer,调用read函数读取文件描述符为sockfd的文件,把读取到的消息存储到buffer中,返回值n为实际读取到的大小,大于0就日志显示是谁发送的,然后执行回调函数_func,并把结果通过write函数写到文件描述符为sockfd的文件上,因为read函数会阻塞,所以需要设置多个判断,为0就说明没有输入,就i显示退出,然后关闭文件,取它的就是出现异常,关闭文件并退出。

 void Service(int sockfd,InetAddr& peer){char buffer[1024];while(true){ssize_t n=read(sockfd,buffer,sizeof(buffer)-1);if(n>0){buffer[n]=0;LOG(LogLevel::DEBUG)<<peer.StringAddr()<<"#"<<buffer;std::string echo_string=_func(buffer,peer);write(sockfd,echo_string.c_str(),echo_string.size());}else if(n==0){LOG(LogLevel::DEBUG)<<peer.StringAddr()<<"退出了";close(sockfd);break;}else{LOG(LogLevel::DEBUG)<<peer.StringAddr()<<"异常";close(sockfd);break;}}}

3.Run函数实现

设置isrunning状态,创建sockaddr_in结构体,得到其大小,调用accept函数开始处理要连接的客服端,如果没有要连接的就会处于阻塞状态,连接成功就可以得到客服端的信息,放到类型为InetAddr的addr内部处理,可以打印出地址信息,接着就是处理任务了,这里方案是创建多线程,pthread_create函数创建线程,传入创建的tid,执行的函数Routine,以及this,执行函数内部是先设置为分离状态,避免阻塞(卡住主线程),创建ThreadData类原因是线程函数只能传一个参数,所以需要把所有的参数封装在一起,把结构体传过去,线程函数执行service函数,service函数内部有回调函数,所以就可以处理任务,拿到结果。

方案二:

通过fork函数创建子进程,id==0时是子进程执行的代码,然后关闭listensock,因为用不上避免错误,接着在创建一个子进程,也就是有爷子孙三个进程,把任务给孙子进程执行,然后关闭子进程,因为父进程要阻塞回收子进程资源,而关闭就不会了,孙子进程因为子进程关闭而变成孤儿进程,就会在任务执行完成后自动结束。

方案三:

线程池方案,使用lambda形式把任务入队列,提前设置线程最多数量,就可以把任务队列的任务取出来执行。

   class ThreadData{public:ThreadData(int fd,InetAddr& ar,TcpServer* s):sockfd(fd),addr(ar),tsvr(s){}public:int sockfd;InetAddr addr;TcpServer* tsvr;};static void* Routine(void* args){pthread_detach(pthread_self());//避免阻塞ThreadData* td=static_cast<ThreadData*>(args);td->tsvr->Service(td->sockfd,td->addr);delete td;return nullptr;}void Run(){_isrunning=true;while(_isrunning){struct sockaddr_in peer;socklen_t len=sizeof(sockaddr_in);int sockfd=accept(_listensockfd,CONV(peer),&len);if(sockfd<0){LOG(LogLevel::WARNING)<<"accept error";continue;}InetAddr addr(peer);LOG(LogLevel::INFO)<<"accept success ,peer addr:"<<addr.StringAddr();//多线程版本ThreadData* td=new ThreadData(sockfd,addr,this);pthread_t tid;pthread_create(&tid,nullptr,Routine,td);// //父进程// pid_t id=fork();// if(id<0)// {//     LOG(LogLevel::FATAL)<<"fork error";//     exit(FORK_ERR);// }// else if(id==0)// {//     //不让子进程访问listensock//     close(_listensockfd);//     if(fork()>0)//         exit(OK);//     Service(sockfd,addr);//     exit(OK);// }// else// {//     close(sockfd);//     pid_t rid=waitpid(id,nullptr,0);//     (void)rid;// }//      //线程池版本,适合于短服务// ThreadPool<task_t>::GetInstance()->Enqueue([this,sockfd,&addr](){// this->Service(sockfd,addr);// });}_isrunning=false;}

4.Server.cc文件

Usage函数目的是命令行参数不足时执行这个函数,主函数获取命令行参数,得到端口号,创建command对象,然后智能指针指向用make_unique创建的对象,这个对象的创建就可以看知道回调函数就是执行execute,参数为端口号和bind绑定的Command内部的函数,也可以不绑定,就是一个端口号和要执行什么任务作为参数,调用创建对象的init函数和run函数。

#include "Command.hpp"
#include "TcpServer.hpp"std::string defaulthandler(const std::string& word,InetAddr& addr)
{LOG(LogLevel::DEBUG)<<"回调到了defaulthander";std::string s="haha ";s+=word;return s;
}void Usage(std::string proc)
{std::cerr<<"Usage:"<<proc<<"port"<<std::endl;
}int main(int argc,char* argv[])
{if(argc!=2){Usage(argv[0]);exit(USAGE_ERR);}uint16_t port=std::stoi(argv[1]);Enable_Console_Log_Strategy();Command cmd;std::unique_ptr<TcpServer> tsvr=std::make_unique<TcpServer>(port,std::bind(&Command::Execute,&cmd,std::placeholders::_1,std::placeholders::_2));tsvr->Init();tsvr->Run();
}

5. Tcpclient.cc文件

读取命令行参数,获得端口号和ip地址,创建套接字,客服端的套接字不需要绑定,避免端口冲突,os会自动随机绑定空的端口,创建类型为InetAddr的serveraddr对象,会对地址和端口号进行处理,执行connect函数,发起连接请求,服务器执行accept函数就会完成连接。while一直循环,创建line读取cin输入流内容,输入流会完line里面写入,执行write函数把line内容写到文件描述符为sockfd的文件,创建buffer,调用read函数把sockfd对应的文件内容读到buffer里面,读取成功打印buffer内容,最后关闭文件。

#include <iostream>
#include "Common.hpp"
#include "InetAddr.hpp"void Usage(std::string proc)
{std::cerr<<"Usage::"<<proc<<"server_ip server_port"<<std::endl;
}int main(int argc,char* argv[])
{if(argc!=3){Usage(argv[0]);exit(USAGE_ERR);}std::string serverip=argv[1];uint16_t serverport=std::stoi(argv[2]);int sockfd=socket(AF_INET,SOCK_STREAM,0);if(sockfd<0){std::cerr<<"sock error"<<std::endl;exit(SOCKET_ERR);}InetAddr serveraddr(serverip,serverport);int n=connect(sockfd,serveraddr.NetAddrPtr(),serveraddr.NetAddrLen());if(n<0){std::cerr<<"connect error"<<std::endl;exit(CONNECT_ERR);}while(true){std::string line;std::cout<<"Please Enter@";getline(std::cin,line);write(sockfd,line.c_str(),line.size());char buffer[1024];ssize_t size=read(sockfd,buffer,sizeof(buffer)-1);if(size>0){buffer[size]=0;std::cout<<"server echo#"<<buffer<<std::endl;}}close(sockfd);return 0;
}

6.Common.hpp文件

实现了一个枚举,跟exit搭配,对应不同退出信息,NoCopy类是不可以靠谱构造和赋值重载的,于继承一起,就可以让禁止拷贝和赋值的类继承这个类,就可以不用在内部写多份(多个类都要满足禁止拷贝和赋值),只要作为NoCopy类的派生类就不可以拷贝和赋值。

#pragma once#include <iostream>
#include <functional>
#include <unistd.h>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>enum ExitCode
{OK=0,USAGE_ERR,SOCKET_ERR,BIND_ERR,LISTEN_ERR,CONNECT_ERR,FORK_ERR
};class NoCopy
{
public:NoCopy() {}~NoCopy() {}NoCopy(const NoCopy&) =delete;const NoCopy& operator=(const NoCopy&) =delete;
};#define CONV(addr) ((struct sockaddr*)&addr)

7.Command.hpp文件

远端执行远程命令,就需要设置一些限制,不然执行一些命令,比如删除,创建这类执行是危险的,成员变量为set的容器,把可以用的命令放到容器中,只用输入这些指令才是有效的,其余都是无用的,issafecommand函数可以判断,通过遍历容器。execute函数是具体的处理,先判断指令是否在容器中,接着执行popen函数,用于子进程来执行指定的命令,并通过管道于子进程的输出进行交互,使用fgets函数从fp指向的文件进行读取内容,按行读取直到没有为止,然后把读取的内容与格式话拼接,把结果返回,然后server端就可以得到最后返回的结果。

#pragma once#include <iostream>
#include <string>
#include <cstdio>
#include <set>
#include "Command.hpp"
#include "InetAddr.hpp"
#include "Log.hpp"using namespace LogModule;class Command
{
public:Command(){_WhiteListCommands.insert("ls");_WhiteListCommands.insert("pwd");_WhiteListCommands.insert("ls -l");_WhiteListCommands.insert("touch haha.txt");_WhiteListCommands.insert("who");_WhiteListCommands.insert("whoami");}bool IsSafeCommand(const std::string& cmd){auto iter=_WhiteListCommands.find(cmd);return iter!=_WhiteListCommands.end();}std::string Execute(const std::string& cmd,InetAddr& addr){if(!IsSafeCommand(cmd)){return std::string("违规");}std::string who=addr.StringAddr();FILE* fp=popen(cmd.c_str(),"r");if(nullptr==fp){return std::string("执行命令不存在:")+cmd;}std::string res;char line[1024];while(fgets(line,sizeof(line),fp)){res+=line;}pclose(fp);std::string result=who+"execute done,result is: \n"+res;LOG(LogLevel::DEBUG)<<result;return result;}~Command(){}
private:std::set<std::string> _WhiteListCommands;
};

 

 

相关文章:

TCP实现多线程远程命令执行

1.上一篇篇代码改进 bind的绑定第一个是对象&#xff0c;其余的都是参数&#xff0c;传给一个类需要this指针&#xff0c;所以有&r 错误地方是智能指针的参数要加&&#xff0c;thread.name()要删除 2.介绍需要用到函数 popen函数 FILE *popen(const char *command, …...

【MySQL】索引特性

文章目录 &#x1f449;没有索引可能会有什么问题&#x1f448;&#x1f449;认识磁盘&#x1f448;前置知识MySQL 与磁盘磁盘定位扇区结论磁盘随机访问与连续访问MySQL 与磁盘交互基本单位 &#x1f449;MySQL 的整体轮廓&#x1f448;&#x1f449;索引的理解&#x1f448;建…...

红宝书第四十七讲:Node.js服务器框架解析:Express vs Koa 完全指南

红宝书第四十七讲&#xff1a;Node.js服务器框架解析&#xff1a;Express vs Koa 完全指南 资料取自《JavaScript高级程序设计&#xff08;第5版&#xff09;》。 查看总目录&#xff1a;红宝书学习大纲 一、框架定位&#xff1a;HTTP服务器的工具箱 共同功能&#xff1a; 快…...

SDK游戏盾ip可以破解吗

从技术实现和法律合规性角度&#xff0c;​​不建议也不应尝试破解SDK游戏盾的IP防护机制​​。以下是详细分析&#xff1a; ​​一、法律与道德风险​​ ​​违法行为​​ 破解游戏盾的IP防护属于​​非法侵入计算机信息系统​​或​​破坏网络安全​​的行为&#xff0c;可能…...

​​eBay东南亚爆单密码:72小时交付计划如何重构厦门仓+东南亚供应链?​

2024年东南亚电商市场规模预计突破2340亿美元&#xff0c;年复合增长率达18%。eBay最新战略将厦门纳入海外仓核心节点&#xff0c;推出“72小时交付计划”&#xff0c;通过“仓配转”一体化链路&#xff0c;助力中国卖家实现东南亚市场订单履约率提升10%&#xff0c;退货成本降…...

大语言模型

1.当前有哪些主流AI方向 1.1大语言模型方向 OpenAI的GPT语言模型系列&#xff0c;o3等推理模型系列 综合能力强 anthrotic的claude系列&#xff0c;推理预测混合模型 代码能力强 DeepSeek的V系列&#xff0c;R1推理模型 …...

深入理解Java缓冲输入输出流:性能优化的核心武器

在Java应用程序的IO操作中,频繁的磁盘读写或网络传输往往是性能瓶颈的主要来源。JDK提供的缓冲流(Buffered Streams)通过内存缓冲机制,将零碎的IO操作转化为批量处理,成为提升IO效率的关键技术。本文将从设计原理、核心机制到实战技巧,全面解析缓冲流的技术细节。 一、缓…...

AI 对话高效输入指令攻略(一):了解AI对话指令

目录 引 一.认识 AI 对话中的指令基础​ 1.运行原理​ 2.智能体在 AI 对话中的关键角色与运行机制​ 3.智能体的核心任务​ 4.对不同指令的响应差异​ 5.针对不同指令类型的处理方式​ 6.智能体在底层逻辑中的运作​ 二.高效输入指令的底层逻辑​ 1.语义匹配逻辑​ …...

AI大模型从0到1记录学习 数据结构和算法 day19

常用算法 查找算法 二分查找 算法原理 二分查找又称折半查找&#xff0c;适用于有序列表。其利用数据的有序性&#xff0c;每轮缩小一半搜索范围&#xff0c;直至找到目标元素或搜索区间为空为止。 代码实现 def binary_search(arr, target): left, right 0, len(arr) - 1 w…...

Python + Playwright:使用正则表达式增强自动化测试

Python + Playwright:使用正则表达式增强自动化测试 前言一、 为什么选择正则表达式?二、 Playwright 中集成正则表达式:途径与方法三、 实战应用:正则表达式解决典型测试难题场景 1:定位 ID 或 Class 包含动态部分的元素场景 2:验证包含可变数字或文本的提示信息场景 3:…...

构建用户友好的记账体验 - LedgerX交互设计与性能优化实践

构建用户友好的记账体验 - LedgerX交互设计与性能优化实践 发布日期: 2025-04-16 引言 在财务管理应用领域&#xff0c;技术实力固然重要&#xff0c;但最终决定用户留存的往往是日常使用体验。本文作为LedgerX技术博客的第二篇&#xff0c;将深入探讨我们如何通过精心的交互…...

AI赋能PLC(一):三菱FX-3U编程实战初级篇

前言 在工业自动化领域&#xff0c;三菱PLC以其高可靠性、灵活性和广泛的应用场景&#xff0c;成为众多工程师的首选控制设备。然而&#xff0c;传统的PLC编程往往需要深厚的专业知识和经验积累&#xff0c;开发周期长且调试复杂。随着人工智能技术的快速发展&#xff0c;利用…...

人工智能——梯度提升决策树算法

目录 摘要 14 梯度提升决策树 14.1 本章工作任务 14.2 本章技能目标 14.3 本章简介 14.4 编程实战 14.5 本章总结 14.6 本章作业 本章已完结&#xff01; 摘要 本章实现的工作是&#xff1a;首先采用Python语言读取含有英语成绩、数学成绩以及学生所属类型的样本数据…...

智能家居适老化改造:让科技回归“无感服务”

在老龄化加速与科技飞速发展的当下&#xff0c;智能家居适老化改造成为提升老年人生活品质的关键举措。 理想的适老化智能家居&#xff0c;应实现 “无感服务”&#xff0c;即让老年人在无需刻意操作或复杂学习的情况下&#xff0c;自然、流畅地享受科技带来的便利&#xff0c…...

2025年最新Web安全(面试题)

活动发起人小虚竹 想对你说&#xff1a; 这是一个以写作博客为目的的创作活动&#xff0c;旨在鼓励大学生博主们挖掘自己的创作潜能&#xff0c;展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴&#xff0c;那么&#xff0c;快来参加吧&#xff01…...

【linux】命令收集

1. 系统信息 uname -m&#xff1a;显示处理器架构uname -r&#xff1a;显示内核版本arch&#xff1a;显示处理器架构cat /proc/cpuinfo&#xff1a;查看CPU信息cat /proc/meminfo&#xff1a;查看内存使用情况cat /proc/version&#xff1a;显示内核版本date&#xff1a;显示系…...

从零到一:网站设计新手如何快速上手?

从零到一&#xff1a;网站设计新手如何快速上手&#xff1f; 在当今数字化时代&#xff0c;网站已成为企业、个人展示信息、提供服务的重要窗口。对于想要涉足网站设计领域的新手而言&#xff0c;如何快速上手并掌握必要的技能成为首要任务。本文将从基础知识、软件工具、设计…...

API平台(API网关)的API安全保障机制

API安全保障机制是一个复杂而重要的任务&#xff0c;需要综合运用多种技术和策略来确保API的安全性和稳定性。 1.黑名单 将不合法的服务、API及终端加入平台黑名单&#xff0c;限制其访问。支持黑名单的列表展示&#xff0c;且可将内容从黑名单删除。按类型、内容搜索黑名单。…...

【软考】论devops在企业信息系统开发中的应用

摘要&#xff1a; 随着互联网的不断发展&#xff0c;各行各业都在建设自己的企业信息系统&#xff0c;而随着业务的不断升级和复杂化&#xff0c;系统的更新迭代速度越来越快&#xff0c;系统也越来越复杂。对于信息系统开发者&#xff0c;架构师&#xff0c;管理者&#xff0c…...

端、管、云一体化原生安全架构 告别外挂式防护!

面对数字化转型浪潮&#xff0c;企业网络安全风险日益凸显。数据泄露、黑客勒索等事件频发&#xff0c;合规要求加速推进。尽管企业纷纷部署了防病毒、身份认证、文件加密、入侵防护、流量监控等多种安全系统&#xff0c;但分散且孤立的架构非但没有有效抵御风险&#xff0c;反…...

每天记录一道Java面试题---day39

GC如何判断对象可以被回收了 回答重点 引用计数法&#xff1a; - 每个对象由一个引用计数属性&#xff0c;新增一个引用时计数器加1&#xff0c;引用释放时计数减1&#xff0c;计数为0时可以回收。可达性分析法&#xff1a; - 从GC Roots开始向下搜索&#xff0c;搜索所走过的…...

码界奇缘 Java 觉醒 后记 第二十五章 安全结界攻防战 - 从沙箱到模块化

第二十五章&#xff1a;安全结界攻防战 - 从沙箱到模块化 知识具象化场景 陆小柒站在由安全策略文件堆砌的古城墙上&#xff0c;眼前是千疮百孔的沙箱结界。空中漂浮着残缺的SecurityManager符石&#xff0c;远处java.security包化身的青铜守卫正在崩塌&#xff1a; 权限校验…...

【数据结构】励志大厂版·初阶(复习+刷题):线性表(顺序表)

前引&#xff1a;上一篇我们复习了复杂度&#xff0c;今天我们来通过实践回忆我们的线性表知识点&#xff0c;下面将讲解什么是线性表&#xff0c;顺序结构又是什么&#xff0c;知识点简洁精髓&#xff0c;无废话可言&#xff0c;小编会从每个细节讲起&#xff0c;包含头文件的…...

C 语言结构体中的函数指针与 Kotlin 高阶函数的对比

在学习 C 语言的过程中&#xff0c;很多 Java/Kotlin 背景的开发者都会对结构体中出现的“函数指针”感到陌生。特别是当看到如下代码时&#xff1a; struct Animal {void (*speak)(void); };void dogSpeak() {printf("Woof!\n"); }int main() {struct Animal dog;d…...

MicroK8s和K8s的区别优劣在哪?

运行ubuntu24.04后提示这么一段话&#xff1a; Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8sjust raised the bar for easy, resilient and secure K8s cluster deployment.https://ubuntu.com/engage/secure-kubernetes-at-the-edge 这段话…...

C++指针和引用之区别(The Difference between C++Pointers and References)

面试题&#xff1a;C指针和引用有什么区 C指针和引用有什么区别&#xff1f; 在 C 中&#xff0c;指针和引用都是用来访问其他变量的值的方式&#xff0c;但它们之间存在一些重要的区别。了解这些区别有助于更好地理解和使用这两种工具。 01 指针 指针&#xff08;Pointer…...

Linux——Shell编程之正则表达式与文本处理器(笔记)

目录 基础正则表达式 1:基础正则表达式示例 &#xff08;4&#xff09;查找任意一个字符“.”与重新字符“*” &#xff08;5&#xff09;查找连续字符范围“{ }” 文本处理器 一、sed工具 二、awk工具 &#xff08;1&#xff09;按行输出文本 &#xff08;2&#xff0…...

关于k8s的部署

一、实验目的 1、理解k8s的组件的功能&#xff1b; 2、理解k8s中的资源类型&#xff1b; 3、 熟练掌握k8s部署配置&#xff1b; 二、实验内容&#xff1a; 前置知识点&#xff1a; 写出k8s有哪些组件并简述作用&#xff1f; ①Master 组件&#xff1a; Master 组件提供集…...

营销自动化实战指南:如何用全渠道工作流引爆线索转化率?

在数字化浪潮席卷全球的今天&#xff0c;企业争夺用户注意力的战场已从单一渠道转向全渠道。然而&#xff0c;面对海量线索&#xff0c;许多团队依然深陷效率泥潭&#xff1a;人工处理耗时费力、高价值线索流失、跨渠道数据难以整合……如何破局&#xff1f;营销自动化正成为企…...

利用Global.asax在ASP.NET Web应用中实现功能

Global.asax文件&#xff08;也称为ASP.NET应用程序文件&#xff09;是ASP.NET Web应用程序中的一个重要文件&#xff0c;它允许您处理应用程序级别和会话级别的事件。下面介绍如何利用Global.asax来实现各种功能。 Global.asax基本结构 <% Application Language"C#&…...

【Linux 并发与竞争实验】

【Linux 并发与竞争实验】 之前学习了四种常用的处理并发和竞争的机制&#xff1a;原子操作、自旋锁、信号量和互斥体。本章我们就通过四个实验来学习如何在驱动中使用这四种机制。 文章目录 【Linux 并发与竞争实验】1.原子操作实验1.1 实验程序编写1.2 运行测试 2.自旋锁实验…...

数据一致性策略之延迟双删-实现

延迟双删 查询数据之前优先去查Redis的缓存数据&#xff0c;减少数据库压力&#xff1b; 如果没有缓存会去查数据库&#xff0c;通过查询数据库后缓存热点Key Cache-Aside策略 高并发场景时&#xff0c;严重生产bug&#xff1a;数据不一致 业务场景&#xff1a; 事务1&#x…...

在PyTorch中,使用不同模型的参数进行模型预热

在PyTorch中&#xff0c;使用不同模型的参数进行模型预热&#xff08;Warmstarting&#xff09;是一种常见的迁移学习和加速训练的策略。以下是结合多个参考资料总结的实现方法和注意事项&#xff1a; 1. 核心机制&#xff1a;load_state_dict()与strict参数 • 部分参数加载&…...

【AI论文】InternVL3:探索开源多模态模型的高级训练和测试时间配方

摘要&#xff1a;我们推出了InternVL3&#xff0c;这是InternVL系列的一项重大进步&#xff0c;具有本地多模态预训练范式。 InternVL3不是将纯文本的大型语言模型&#xff08;LLM&#xff09;改编成支持视觉输入的多模态大型语言模型&#xff08;MLLM&#xff09;&#xff0c;…...

基于Linux的ffmpeg python的关键帧抽取

1.FFmpeg的环境配置 首先强调&#xff0c;ffmpeg-python包与ffmpeg包不一样。 1) 创建一个虚拟环境env conda create -n yourenv python3.x conda activate yourenv2) ffmpeg-python包的安装 pip install ffmpeg-python3) 安装系统级别的 FFmpeg 工具 虽然安装了 ffmpeg-p…...

CNN:卷积到底做了什么?

卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09; 是一种深度学习模型&#xff0c;专门用于处理具有网格结构的数据&#xff08;如图像、视频等&#xff09;。它在计算机视觉领域表现卓越&#xff0c;广泛应用于图像分类、目标检测、图像分割等任务。CN…...

C++ IO流

文章目录 C IO流流是什么C标准IO流C文件IO流c字符串流 C IO流 流是什么 在 C 中&#xff0c;“流&#xff08;Stream&#xff09;” 是一种 抽象的数据传输机制&#xff0c;它通过统一的接口实现了程序与各种输入/输出设备&#xff08;如键盘、屏幕、文件、内存等&#xff09…...

解决splice改变原数组的BUG(拷贝数据)

项目场景&#xff1a; 项目中难免遇到需要删除改变数组的方法&#xff0c;去重&#xff0c;删除不要的数据等 问题描述&#xff1a; 但是splice方法会删除掉数据改变原数组&#xff0c;返回的是改变之后的数组&#xff0c;即使你是赋值的还是会影响到原数组的数据 GoodsInfo…...

ARINC818协议(二)

ARINC818对图像数据进行帧分割 1.FC协议定了5层模型结构&#xff1a;FC-4;FC-3;FC-2;FC-1;FC-0; 2.ARINC818协议位于FC-4层&#xff1b; 3.ARINC818协议在FC-4层使用FHCP帧头控制协议进行实现数据传递&#xff1b; 4.协议中有容器&#xff0c;容器头&#xff0c;object0~object…...

【Netty篇】Future Promise 详解

目录 一、 Netty Future 与 Promise —— 异步世界的“信使”与“传话筒”&#x1f680;1、 理解 Netty Future2、 理解 Netty Promise 二、 代码案例解读&#x1f4bb;例1&#xff1a;同步处理任务成功&#x1f44d;例2&#xff1a;异步处理任务成功&#x1f4f2;例3&#xff…...

【LaTeX】Misplaced alignment tab character . ^^I

目录 公式中出现Misplaced alignment tab character &. ^^I& 解决1&#xff1a;采用&& 解决2&#xff1a; 公式中出现Misplaced alignment tab character &. ^^I& \begin{equation}J_r & \dfrac{i\hbar}{2m}\left[\psi_2 \dfrac{\partial \psi^…...

数据中台(大数据平台)之元数据管理

&#x1f449;元数据管理是数据管理的基础&#xff0c;数据中台产品要能够提供各类元数据采集的适配器&#xff0c;自动化采集技术元数据&#xff0c;并在技术元数据的基础上补充管理属性和业务属性&#xff0c;为后续的数据资源目录、数据安全管控、报表开发提供统一的口径。并…...

基于RRT的优化器:一种基于快速探索随机树算法的新型元启发式算法

受机器人路径规划中常用的快速探索随机树&#xff08;RRT&#xff09;算法的搜索机制的启发&#xff0c;我们提出了一种新颖的元启发式算法&#xff0c;称为基于RRT的优化器&#xff08;RRTO&#xff09;。这是首次将RRT算法的概念与元启发式算法相结合。RRTO的关键创新是其三种…...

设计模式每日硬核训练 Day 13:桥接模式(Bridge Pattern)完整讲解与实战应用

&#x1f504; 回顾 Day 12&#xff1a;装饰器模式小结 在 Day 12 中&#xff0c;我们学习了装饰器模式&#xff08;Decorator Pattern&#xff09;&#xff1a; 强调在不改变原类结构的前提下&#xff0c;动态为对象增强功能。通过“包装对象”实现运行时组合&#xff0c;支…...

【开发语言】悬空指针问题

悬空指针&#xff08;Dangling Pointer&#xff09;是编程中常见的内存管理问题&#xff0c;尤其在C/C这类手动管理内存的语言中。以下是详细解释&#xff1a; 什么是悬空指针&#xff1f; 悬空指针是指向已经被释放&#xff08;或失效&#xff09;内存的指针。这段内存可能已…...

深入剖析 WiFi 定位解析功能:原理、技术优势与应用场景

WiFi 定位解析功能的原理​ 信号强度与距离的关系​ WiFi 定位的核心原理基于无线信号传播过程中的一个基本特性&#xff1a;信号强度与信号发射源&#xff08;即 WiFi 接入点&#xff0c;Access Point&#xff0c;简称 AP&#xff09;和接收设备之间距离的关联。一般来说&am…...

从标准九九表打印解读单行表达式的书写修炼(Python)

解读单行表达式书写&#xff0c;了解修习单行捷径。 笔记模板由python脚本于2025-04-16 23:24:17创建&#xff0c;本篇笔记适合喜欢单行喜好python的coder翻阅。 【学习的细节是欢悦的历程】 博客的核心价值&#xff1a;在于输出思考与经验&#xff0c;而不仅仅是知识的简单复述…...

HTML5好看的水果蔬菜在线商城网站源码系列模板4

文章目录 1.设计来源1.1 主界面1.2 关于我们1.3 商品信息1.4 新闻资讯1.5 联系我们1.5 登录注册 2.效果和源码2.1 动态效果2.2 源代码 源码下载 作者&#xff1a;xcLeigh 文章地址&#xff1a;https://blog.csdn.net/weixin_43151418/article/details/147264262 HTML5好看的水果…...

Arkts应用全局UI状态存储和持久化V2(AppStorageV2、PersistenceV2和@Type)

目录 应用全局UI状态存储和持久化V2版本 AppStorageV2 connect remove keys 示例 使用限制 PersistenceV2 connect remove keys save notifyOnError 示例 使用限制 Type 使用限制 应用全局UI状态存储和持久化V2版本 以下实例AppStorageV2、PersistenceV2和装饰…...

【QT】常用控件 【多元素类 | 容器类 | 布局类】

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Qt 目录 一&#xff1a;&#x1f525; QT 常用控件【多元素类】 &#x1f98b; List Widget -- 列表&#x1f98b; Table Widget -- 表格&#x1f98b; Tree Widget -- 树形 二&#xff1a;&#x…...