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);
}

posted @ 2024-04-12 15:44  HL棣  阅读(13)  评论(0编辑  收藏  举报