简易嵌入式管理平台 C 实现
- 这是经过粗略测试的代码
- 之前做过的 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 实现相关推荐
- Qt编写物联网管理平台(支持win/linux/mac/嵌入式linux/modbus等)
一.前言 这个物联网综合管理平台前后迭代了五年,一点一滴慢慢积累起来,从最开始的只有modbus串口协议解析以及简单的表格显示数据,慢慢的逐渐增加了tcp_rtu支持,用户管理模块,地图监控模块,而后 ...
- qt combox选中消息_Qt+imx6编写的楼宇对讲管理平台
一.前言 Qt是一个非常强大的框架,尤其是GUI展示这块,他的跨平台特性相当牛逼,尽管现在安卓大量蚕食嵌入式linux的市场,Qt依然顽强的以其独有的优势生存着,本人自从C#转成Qt以来,就再也不想回 ...
- 喜报!DT最新通用管理平台开源了
DT ADMIN管理系统 前言 一.核心架构 二.登录注册 1.认证授权 三.后台主页 1.侧边栏 2.顶部 3.整体结构 四.前台主页 五.简易使用 总结 前言 最近小编花夜晚时间,把DT ADMI ...
- Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere
前言 Kubernetes(K8s)集群管理平台都是基于 Kubernetes 提供功能,可以说他们是在 K8s 的基础上封装了一层更为友好的操作方式.他们都是为了降低 k8s 集群运维复杂度,降低运 ...
- java适合做平台_java不适合做单机web管理平台的2大因素
[IT168 评论]作者所说的单机管理程序是网络设备的web管理平台,例如防火墙的web管理界面,或者路由器的web管理界面.其中大多数使用php,还有wrt系列使用Lua,甚至有使用perl的,单机 ...
- 计算机毕业设计ssm游泳馆管理平台
最新计算机专业原创毕业设计参考选题都有源码+数据库是近期作品 你的选题刚好在下面有,有时间看到机会给您发 1 ssm球迷信息交流论坛 2 springboot基于SpringBoot的在线古玩市场系统 ...
- 嵌入式 Linux平台 C程序 交叉编译技术
嵌入式Linux平台C程序交叉编译技术 一.实验目的和任务 本实验要求复习和掌握Linux平台的C程序开发过程. 本实验要求掌握嵌入式开发板的操作方法. 本实验要求掌握Linux平台交叉编译方法和程序 ...
- 前后端对接及接口管理平台浅析
关与作者更多博客请访问云里云外开源社区 文章目录 一.接口是什么(附带简易案例) 二.Tomcat的Servlet 三.json 四.接口文档: 五.管理平台 每一个完整的项目都是不是一个人的功劳,是 ...
- 智能运维监控管理平台技术方案
目 录 1 项目概况 7 1.1 项目背景 7 2 现状概述 7 2.1 当前现状分析 7 2.2 当前面临的运维问题 7 3 需求分析 8 3.1 传统运维工具局限性 8 3.2 具体需求分析 8 ...
最新文章
- Go 学习笔记(18)— 函数(04)[闭包定义、闭包修改变量、闭包记忆效应、闭包实现生成器、闭包复制原对象指针]
- matplotlib pcolormech 用法
- CTO集体怒吼:我到底要不要继续写代码(下篇)
- Fedora相关(一)
- sklearn学习(二)
- MySQL的user表
- 克隆仓库时HTTPS和SSH方式的区别和使用
- python网络编程(八)
- 《阿里云SRE技术期刊》2020年10月【电子版】
- SAPGUI系统登录页面配置的SAProuter有什么用 2
- 20155317 王新玮 2016-2017-2 《Java程序设计》第5周学习总结
- c语言输出七个换行6,多样例输出,如何去掉最后一个回车
- android流媒体架构,基于Android平台的流媒体播放器的设计与实现
- 用java数组实现栈
- d va爬黑板animate_复合绝缘子的爬电距离(注电案例1295)
- DC离职率预测案例分析
- IT编程自学与培训的优缺点对比!
- rtx3090显卡什么级别 rtx3090显卡什么水平 3090属于什么档次的显卡
- java对word文档的操作
- Element-UI源码之目录结构
热门文章
- ios开发常识(1)开发语言和参考资料
- BookBlock - 效果非常真实的书本翻页预览
- 菜鸟学python 哪吒_Python 学习之路 (前言)
- hls fifo_【FCCM2020】HLS 高手对比 Verilog 高手,到底输哪了?
- webpack打包转换es6_webpack(二)解析es6并打包
- linux ssh连接交换机_java通过ssh协议管理交换机,linux
- centos 静态ip_CentOS 6 静态 IP 配置
- oracle事务数统计,oracle函数与事务
- 直系同源基因ks_哈佛医学院开发出新的Cas9变体,可以靶向基因组绝大部分序列...
- 奇数页分节符什么意思_删除分节符问题