• 这是经过粗略测试的代码
  • 之前做过的 C 的命令行 调试程序 遵循 MIT 协议, 有配套的 前端, 之前写的开源的一套测试程序
  • 用了一个大哥开源的 ARM_WEB 前端框架,适合arm的管理web,很小,我的js 和 html 写的像屎一样
  • 以后估计再写的话直接使用Rust 衔接了

这是client
server 端的代码 在这里 还有一个web 的处理程序 在里面应该
https://gitee.com/hongdayugitee/c_-cli.git

httpd 上使用的 C 语言的 cgi
https://gitee.com/hongdayugitee/c_-cgi.git

Web 前端代码和 python3 网页接口测试程序,全是 用的古老的cgi
https://gitee.com/hongdayugitee/arm_web.git

#include <stdio.h>
#include "readline/readline.h" //readline的bash 补全库,可以使用静态编译使用;Arm 板卡的移值和操作
#include <readline/history.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include<sys/select.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#include<unistd.h>
#include <errno.h>
#include <sys/stat.h>static int udp_fd; //作为命令行全局使用的描述符;
char *dupstr(char *s) {char *r;r = (char *) calloc(strlen(s) + 1, sizeof(char));strcpy(r, s);return (r);
}// 申请一个内存池的空间大约8096bytes 大约 8K的缓存区 res的空间最大就只有的8K的大小;
/* 系统级的调试对普通的命令行的解析 发送命令并等待命令回复 */
int deal_request_and_parse(char *data, char *record) { //返回的record为正常可以使用的数据;处理和解析的模块儿udp_fd = socket(AF_INET, SOCK_DGRAM, 0);int enable_select = 1;int res;char *tmp;char buf[8096] = {0};fd_set rx_check;struct timeval timeout = {.tv_usec = 500,.tv_sec = 2};struct sockaddr_in server;server.sin_family = AF_INET;server.sin_port = htons(2022); //发送->2021端口server.sin_addr.s_addr = inet_addr("127.0.0.1"); //本机间的进程间通信if (setsockopt(udp_fd, SOL_SOCKET, SO_REUSEADDR, &enable_select, sizeof(int)) == -1) {printf("sys error:%s\n", strerror(errno));}socklen_t addrlen = sizeof(struct sockaddr);res = (int) sendto(udp_fd, data, strlen(data), 0, (struct sockaddr *) &server, addrlen);if (res < 0) {printf("error=-1"); //网页中显示和使用错误代码处理goto ERROR;}FD_ZERO(&rx_check);FD_SET(udp_fd, &rx_check);res = select(udp_fd + 1, &rx_check, NULL, NULL, &timeout);if (res < 0) {printf("CLI PARSE SELECT SOCKET ERROR\n"); //select 选择出错;出现系统级别的错误goto ERROR;} else if (res == 0) { //监听超时;普通的命令解析和校验;返回命令和反馈结果;printf("CLI CAN'T CONNNECT TO DRIVER SERVICE\n");exit(0);goto ERROR;}int len = (int) recvfrom(udp_fd, buf, 8096, 0, NULL, NULL);if (len == 0) {printf("CLI GET RESTULT LEN IS ZERO\n"); //可以和服务器通信,但是查询不到数据,发送的都是字符数据忽视发送的bit数据;对bit数据可以忽略不计;// 其实都是ASCII码的使用;goto ERROR;} else if (len > 0) {if (record != NULL) {tmp = record + len;           //对传入的参数的空间大小的验证if (tmp != NULL) {memcpy(record, buf, len); //buf和tmp的内存空间不同;不用考虑内存交叉的问题;}} else {printf("%s\n", buf);}}
ERROR: //如果出错并汇报错误类型;有命令就会解析;没有命令就不会解析close(udp_fd);return 0;
}void read_config_file_and_exec(const char *path) {FILE *config;config = fopen(path, "r");if (config == NULL) {printf("config file open error:%s\n", strerror(errno));return;}struct stat file_size;if (stat(path, &file_size) < 0) {printf("get config file error:%s\n", strerror(errno));return;}char *buf_pool = (char *) calloc(file_size.st_size, sizeof(char));if (buf_pool == NULL) {printf("calloc mem for config read buffer error\n");return;}fread(buf_pool, file_size.st_size, 1, config);int len = (int)file_size.st_size;while(len--){ //替换完所有的脚本中的换行符号if(buf_pool[len] == '\n'){buf_pool[len] = ';';}}//同时校验脚本的配置是否符合脚本的规则char result[4096] = {0}; //限定到的字节数为4O96个字节数;char *tmp = (char*)calloc(file_size.st_size+strlen("CLI_MSG=FILE_SCRIPT:"),sizeof(char));if(tmp == NULL){printf("calloc mem error\n");return;}strcat(tmp,"CLI_MSG=FILE_SCRIPT:");strncat(tmp,buf_pool,strlen(buf_pool));deal_request_and_parse(tmp, result); //发送查看请求的内容是否是正确的    free(tmp);tmp = NULL;if (result[0] != 0) {printf("exec result:\n%s\n", result);}
}/* 创建一个 STACK 结构 CMD= 256 条命令进行使用*/
static char *command_list[256] = {[0]="exit",[1]="quit",[2]="bye",[255]=(char *) NULL //最后补全的命令为NULL;
};char *cmd_generator(const char *text, int state) {static int i, len;char *name;if (!state) {i = 0;len = (int) strlen(text);}while (name = command_list[i]) { //检索命令行并进行补全;i++;if (strncmp(name, text, len) == 0) {return dupstr(name);}}return NULL;
}char **debug_cli_completion(const char *text, int start, int end) {char **matches;matches = (char **) NULL;if (start == 0) {matches = rl_completion_matches(text, cmd_generator);}return matches;
}void init_readline(void) {rl_readline_name = "DEBUG_CLI";rl_attempted_completion_function = debug_cli_completion;
}char *stripwhite(char *string) {register char *s, *t;for (s = string; whitespace(*s); s++) { ;}if (*s == 0) {return s;}t = s + strlen(s) - 1;while (t > s && whitespace(*t)) {t--;}*++t = 0;return s;
}void deal_complete(char *pool){char *ptr;int i = 3;while ((ptr = strsep(&pool, " ")) != NULL) { //";" 为分隔符 一个命令if (!strcmp(ptr, "")) break; //多一个空字符的情况;特殊情况;必须将空字符去除才可以使用;一般是发生在分隔符的后边;if(i == 255){printf("CMD IS FULL PLEASE CHECK YOUR DRIVER SERVICE\n");break;}command_list[i] = (char*) calloc(256,sizeof(char));if(strlen(ptr) > 255){printf("Command is too long\n");return;}strncpy(command_list[i],ptr, strlen(ptr));i++;}
}void get_complete(void){char cmd[] = "CLI_MSG=EXEC:COMPLETE";char res[2048]={0};deal_request_and_parse(cmd,res);deal_complete(res);
}void exec_line(char *pool){char cmd[] = "CLI_MSG=EXEC:";char *tmp;if(pool != NULL){tmp = (char*)calloc(strlen(cmd)+2*strlen(pool),sizeof(char));strcat(tmp,cmd);strcat(tmp,pool);deal_request_and_parse(tmp, NULL);if(tmp != NULL){free(tmp);tmp = NULL;}}
}int main(int argc, char **argv) {char *line, *s;if (argv[1] != NULL && !strcmp(argv[1], "-f") && argv[2] != NULL) {read_config_file_and_exec(argv[2]); //解析脚本并对脚本进行执行操作;return 0;}get_complete();init_readline();while (1) {line = readline("dcli> ");if (!line) break;s = stripwhite(line);if (*s) {add_history(s);if (!strcmp(s, "exit") || !strcmp(s, "quit") || !strcmp(s, "bye")) {exit(0);}exec_line(s);}free(line);line = NULL;}exit(0);
}

简易嵌入式管理平台 C 实现相关推荐

  1. Qt编写物联网管理平台(支持win/linux/mac/嵌入式linux/modbus等)

    一.前言 这个物联网综合管理平台前后迭代了五年,一点一滴慢慢积累起来,从最开始的只有modbus串口协议解析以及简单的表格显示数据,慢慢的逐渐增加了tcp_rtu支持,用户管理模块,地图监控模块,而后 ...

  2. qt combox选中消息_Qt+imx6编写的楼宇对讲管理平台

    一.前言 Qt是一个非常强大的框架,尤其是GUI展示这块,他的跨平台特性相当牛逼,尽管现在安卓大量蚕食嵌入式linux的市场,Qt依然顽强的以其独有的优势生存着,本人自从C#转成Qt以来,就再也不想回 ...

  3. 喜报!DT最新通用管理平台开源了

    DT ADMIN管理系统 前言 一.核心架构 二.登录注册 1.认证授权 三.后台主页 1.侧边栏 2.顶部 3.整体结构 四.前台主页 五.简易使用 总结 前言 最近小编花夜晚时间,把DT ADMI ...

  4. Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere

    前言 Kubernetes(K8s)集群管理平台都是基于 Kubernetes 提供功能,可以说他们是在 K8s 的基础上封装了一层更为友好的操作方式.他们都是为了降低 k8s 集群运维复杂度,降低运 ...

  5. java适合做平台_java不适合做单机web管理平台的2大因素

    [IT168 评论]作者所说的单机管理程序是网络设备的web管理平台,例如防火墙的web管理界面,或者路由器的web管理界面.其中大多数使用php,还有wrt系列使用Lua,甚至有使用perl的,单机 ...

  6. 计算机毕业设计ssm游泳馆管理平台

    最新计算机专业原创毕业设计参考选题都有源码+数据库是近期作品 你的选题刚好在下面有,有时间看到机会给您发 1 ssm球迷信息交流论坛 2 springboot基于SpringBoot的在线古玩市场系统 ...

  7. 嵌入式 Linux平台 C程序 交叉编译技术

    嵌入式Linux平台C程序交叉编译技术 一.实验目的和任务 本实验要求复习和掌握Linux平台的C程序开发过程. 本实验要求掌握嵌入式开发板的操作方法. 本实验要求掌握Linux平台交叉编译方法和程序 ...

  8. 前后端对接及接口管理平台浅析

    关与作者更多博客请访问云里云外开源社区 文章目录 一.接口是什么(附带简易案例) 二.Tomcat的Servlet 三.json 四.接口文档: 五.管理平台 每一个完整的项目都是不是一个人的功劳,是 ...

  9. 智能运维监控管理平台技术方案

    目 录 1 项目概况 7 1.1 项目背景 7 2 现状概述 7 2.1 当前现状分析 7 2.2 当前面临的运维问题 7 3 需求分析 8 3.1 传统运维工具局限性 8 3.2 具体需求分析 8 ...

最新文章

  1. Go 学习笔记(18)— 函数(04)[闭包定义、闭包修改变量、闭包记忆效应、闭包实现生成器、闭包复制原对象指针]
  2. matplotlib pcolormech 用法
  3. CTO集体怒吼:我到底要不要继续写代码(下篇)
  4. Fedora相关(一)
  5. sklearn学习(二)
  6. MySQL的user表
  7. 克隆仓库时HTTPS和SSH方式的区别和使用
  8. python网络编程(八)
  9. 《阿里云SRE技术期刊》2020年10月【电子版】
  10. SAPGUI系统登录页面配置的SAProuter有什么用 2
  11. 20155317 王新玮 2016-2017-2 《Java程序设计》第5周学习总结
  12. c语言输出七个换行6,多样例输出,如何去掉最后一个回车
  13. android流媒体架构,基于Android平台的流媒体播放器的设计与实现
  14. 用java数组实现栈
  15. d va爬黑板animate_复合绝缘子的爬电距离(注电案例1295)
  16. DC离职率预测案例分析
  17. IT编程自学与培训的优缺点对比!
  18. rtx3090显卡什么级别 rtx3090显卡什么水平 3090属于什么档次的显卡
  19. java对word文档的操作
  20. Element-UI源码之目录结构

热门文章

  1. ios开发常识(1)开发语言和参考资料
  2. BookBlock - 效果非常真实的书本翻页预览
  3. 菜鸟学python 哪吒_Python 学习之路 (前言)
  4. hls fifo_【FCCM2020】HLS 高手对比 Verilog 高手,到底输哪了?
  5. webpack打包转换es6_webpack(二)解析es6并打包
  6. linux ssh连接交换机_java通过ssh协议管理交换机,linux
  7. centos 静态ip_CentOS 6 静态 IP 配置
  8. oracle事务数统计,oracle函数与事务
  9. 直系同源基因ks_哈佛医学院开发出新的Cas9变体,可以靶向基因组绝大部分序列...
  10. 奇数页分节符什么意思_删除分节符问题