linux C++程序测试命令的一种实现
linux C++程序测试命令的一种实现
前言
在程序开发调试过程中,或者已经部署的情况下,我们常常需要执行一些测试命令。在命令行端输入命令,然后程序执行,说起来简单,但是当程序本身有很多终端调试信息输出时,命令输入很不方便。
针对上述问题,以下提供一个使用消息队列的命令行测试小工具代码实现。
1. 命令发送小工具实现代码
test_cmd_send.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
#include <sys/ipc.h>
struct msgmbuf{/*消息的缓冲区结构*/
long mtype; // 注意long与int的字长问题
char mtext[50];
};
int main(){
int ret = -1;
int smsg_id ,rmsg_id; /*收消息与发消息的队列id*/
key_t key1,key2; /*队列的键值*/
struct msgmbuf msg_mbuf;/*创建消息缓冲区*/
struct msgmbuf msg_revbuf;
/*生成消息队列键值, 参数1为目录路径,目录必须已经存在*/
key1 = ftok("/home/work_HLD",'a');
key2 = ftok("/home/work_HLD",'b');
if(key1 != -1 || key2 != -1)/*产生key成功*/
{
printf("成功建立KEY\n");
}
else/*产生key失败*/
{
printf("建立KEY失败\n");
}
smsg_id = msgget(key1, IPC_CREAT|0666); /*建立收消息的消息队列*/
rmsg_id = msgget(key2, IPC_CREAT|0666); /*建立发消息的消息队列*/
if( -1 == smsg_id || -1 == rmsg_id)
{
printf("消息建立失败\n");
return 0;
}
pid_t pid;
pid = fork();/*通过fork()创建子进程,主进程进行发消息,子进程进行收消息*/
while(1){
if(pid != 0){/*主进程*/
msg_mbuf.mtype = 10;/*设置发送的消息类型*/
sleep(1);
char content[50];
memset(content, 0, 50);
printf("input x,y,θ,:\n");
scanf("%s",content);/*用户输入内容*/
if(strncmp(content,"end",3) == 0)/*如果前三个字符为end,则跳出循环*/
break;
memcpy(msg_mbuf.mtext, content, strlen(content));/*复制字符串*/
ret = msgsnd(smsg_id, &msg_mbuf, strlen(content), IPC_NOWAIT);/*发送消息*/
if( -1 == ret)
{
printf("发送消息失败\n");
}
}
else{/*子进程*/
sleep(1);
msg_revbuf.mtype = 10;/*设置收消息的类型*/
ret = msgrcv(rmsg_id, &msg_revbuf, 50, 0, IPC_NOWAIT);/*接收消息*/
if( -1 == ret)
{
/*可添加出错处理等*/
}
else
{
printf("执行结果:%s\n",msg_revbuf.mtext);
}
}
}
msgctl(smsg_id, IPC_RMID,NULL);
ret = msgctl(rmsg_id, IPC_RMID,NULL);/*删除收消息的队列*/
if(-1 == ret)
{
printf("删除消息失败\n");
return 0;
}
return 0;
}
2. 被测试程序接收消息实现代码
main.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
struct msgmbuf{/*消息的缓冲区结构*/
long mtype; // 注意long与int的字长问题
char mtext[50];
};
void test_cmd_run(Balcony_Spray *robot, int rid, int sid)
{
if (rid == -1 || sid == -1 ) return;
struct msgmbuf msg_mbuf; /*创建消息缓冲区*/
int ret = msgrcv(rid, &msg_mbuf, 50, 0,IPC_NOWAIT);/*接收消息*/\
if( -1 == ret)
{
/*可添加出错处理等*/
}
else
{
string content(msg_mbuf.mtext);
Rotating_Info("======>接收消息成功,长度:{}\n",ret);
Rotating_Info("content:{}\n",content);
std::vector<string> string_split;
boost::split(string_split, content, boost::is_any_of(","), boost::token_compress_on);
if (string_split.size() >= 3)
{
//执行命令
//等待执行完成
string result = "执行完成!";
/*反馈运行结果*/
ret = msgsnd(sid, result, result.size(), IPC_NOWAIT);
}
}
}
int main(int argc, char **argv)
{
int ret = -1;
int rmsg_id = -1; /*创建消息队列函数所用的标志位,以及收消息与发消息的队列id*/
int smsg_id = -1;
key_t key1 = -1;
key_t key2 = -1;
key1 = ftok("/home/work_HLD",'a');/*队列的键值*/
key2 = ftok("/home/work_HLD",'b');/*队列的键值*/
if(key1 != -1 && key2 != -1)/*产生key成功*/
{
rmsg_id = msgget(key1, IPC_CREAT|0666); /*建立收消息的消息队列*/
smsg_id = msgget(key2, IPC_CREAT|0666); /*建立发消息的消息队列*/
if (rmsg_id != -1 && smsg_id != -1) Rotating_Info("======>创建队列成功!");
}
else
{
Rotating_Info("======>创建队列失败!");
}
std::thread([dev_control, rmsg_id, smsg_id]() {
while(1)
{
test_cmd_run(dev_control, rmsg_id , smsg_id);
usleep(50*1000);
}
}).detach();
while(1){ usleep(10*1000); };
/*删除收消息的队列*/
msgctl(rmsg_id, IPC_RMID,NULL);
msgctl(smsg_id, IPC_RMID,NULL);
}