当前位置: 首页> 健康> 养生 > 房屋平面设计软件手机版_企业解决方案有哪些_湖南企业seo优化推荐_什么平台免费推广效果最好

房屋平面设计软件手机版_企业解决方案有哪些_湖南企业seo优化推荐_什么平台免费推广效果最好

时间:2025/8/24 7:22:55来源:https://blog.csdn.net/fax_player/article/details/143352319 浏览次数:0次
房屋平面设计软件手机版_企业解决方案有哪些_湖南企业seo优化推荐_什么平台免费推广效果最好

fe594ea5bf754ddbb223a54d8fb1e7bc.gif

目录

代码前身

多线程远程命令执行

命令处理

疑难杂症

基本框架 

添加指令判断函数

最终命令处理

Main主函数

safe.txt

实现效果

全部代码


 

代码前身

verson2:多线程&&线程池 · 516aa13 · 玛丽亚后/keep - Gitee.com

多线程远程命令执行

基本流程:由客户端发送命令,然后服务端接收并执行命令~

当前我们是把处理命令的业务交给回调函数去执行,服务端只需要读取命令即可~

命令处理

接下来我们来对命令方面的处理进行封装~

疑难杂症

但在学习前我将提出几点疑问~

按照我的逻辑客户端发送命令,服务端接收并读取命令后将命令重定向到输入端相当于执行命令,这样就够了吧~

但真正的情况是有两种方法:

第一种:1.fork&&pipe  2.dup(管道重定向)3.exec(执行外部命令函数)  3.dup  

其一:为什么创建子进程,万一该命令是杀死进程那服务端岂不是被中断服务了,所以创建子进程可以保证服务端不会因为其他异常而退出,因为父子进程之间是独立的。

其二:为什么要创建管道,通过管道,父进程可以捕获子进程的标准输出(stdout),从而获取外部命令的执行结果。父进程读取命令,创建子进程去执行命令,子进程执行结果通过管道返回给父进程,父进程拿到结果再返回给客户端~

但这种方法有一个问题:命令本身就是要创建进程,而我们的背景又是多线程~这样就会出现线程去创建进程的结果,不太推荐~

第二种:popen:底层自动建立管道与子进程 

  • popen 会返回一个 FILE * 类型的指针,这个指针可以用于读取子进程的输出(如果模式为 "r")或向子进程发送输入(如果模式为 "w")。

使用popen函数只需要知道它默认让父进程去读取子进程执行的结果,我们只要确保父进程成功接收命令即可,其他事情不用我们担心,它会内部实现,我们等待结果就好了~

基本框架 

//以空格作分隔符
const std::string sep = " ";class Command
{
public:Command(){}//对命令的处理std::string Excute(const std::string &cmd) // ls -a -l{//popen :由底层自动去建立管道与子进程 再通过file* 去读取cmd执行结果FILE* fp = popen(cmd.c_str(),"r");if(fp==nullptr){return "failed";}std::string result;//作为读取命令的缓冲区char buffer[1024];while(fgets(buffer,sizeof(buffer),fp)!=NULL){//把最终命令读取并记录到result中result+=buffer;}pclose(fp);return result;}~Command(){}private:
};

客户端启动参考

int main(int argc, char *argv[])
{Command cmd;std::string res = cmd.Excute("ls -a -l");std::cout<<res;return 0;
}

接下来我们要把一些安全指令加载进Command中,只有识别到是安全命令才会去执行

private://加载安全指令到Command中void LoadConf(const std::string &conf){//打开路径下的安全指令配置文件std::ifstream in(conf);if (!in.is_open()){LOG(FATAL, "open %s error\n", conf.c_str());return;}std::string line;while (std::getline(in, line)){LOG(DEBUG, "load command [%s] success\n", line.c_str());_safe_cmd.insert(line);}in.close();}

添加指令判断函数

 //安全指令判断bool SafeCheck(const std::string & cmd){//验证当前指令是否为已收录的安全指令auto iter = _safe_cmd.find(cmd);if(iter==_safe_cmd.end()){return false;}return true;}

最终命令处理

 // 对命令的处理std::string Excute(const std::string &cmd) // ls -a -l{// 检查是否为安全指令std::string result;if (SafeCheck(cmd)){// popen :由底层自动去建立管道与子进程 再通过file* 去读取cmd执行结果//父进程接收指令,子进程执行FILE *fp = popen(cmd.c_str(), "r");if (fp == nullptr){return "failed";}std::string result;// 作为读取指令结果的缓冲区char buffer[1024];//按行读取while (fgets(buffer, sizeof(buffer), fp) != NULL){// 把最终命令读取并记录到result中result += buffer;}pclose(fp);return result;}else{result = "非法指令\n";}return result;}

Main主函数

void Usage(std::string proc)
{std::cout << "Usage:\n\t" << proc << " local_port\n" << std::endl;
}// ./tcpserver port
int main(int argc, char *argv[])
{if(argc != 2){Usage(argv[0]);return 1;}EnableScreen();uint16_t port = std::stoi(argv[1]);//初始化配置文件路径Command cmd("./safe.txt");//绑定命令处理接口,服务端只要接收到客户端的指令立马通过调用函数去调用该接口func_t cmdExec = std::bind(&Command::Excute, &cmd, std::placeholders::_1);std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>(port, cmdExec);tsvr->InitServer();tsvr->Loop();return 0;
}

safe.txt

ls -a -l
pwd
tree
whoami
who
uname
cat
touch

实现效果

不过也有太死板的地方,我们再来改进一下~

std::string PrefixCommand(const std::string &cmd){if (cmd.empty())return std::string();auto pos = cmd.find(sep);if (pos == std::string::npos)return cmd;elsereturn cmd.substr(0, pos);}// 安全指令判断bool SafeCheck(const std::string &cmd){std::string prefix = PrefixCommand(cmd);// 验证当前指令是否为已收录的安全指令auto iter = _safe_cmd.find(prefix);if (iter == _safe_cmd.end()){return false;}return true;}

全部代码

远程命令服务 · dfdd1d1 · 玛丽亚后/keep - Gitee.com

关键字:房屋平面设计软件手机版_企业解决方案有哪些_湖南企业seo优化推荐_什么平台免费推广效果最好

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: