#pragma once
#include <cstdio>
#include <cstdlib>
#include <sys/msg.h>
#include <cstring>
#include <atomic>
typedef void (*mq_recv_call_handler)(int recv_len,char *recv_buf);
struct msg_st
{
long int msg_type;//作为一个标志,非0:表示可读,0表示可写
char text[BUFSIZ];
};
class mq_helper
{
public:
//mark:队列名称
//send_code:发送码
//recv_code:接收码
mq_helper(int mark, int send_code, int recv_code);
~mq_helper();
bool mq_create();
bool mq_delete(); //服务端调用即可
int mq_write(const char* buf, int size);
void mq_set_recv_call(mq_recv_call_handler fun);
void mq_loop_start();
int _mq_read(char* buf);
void stop();
public:
std::atomic_bool m_exit;
int m_mark;
int m_msgid;
long int m_msgtype;
int m_recv_code;
int m_send_code;
msg_st m_data_recv;
msg_st m_data_send;
mq_recv_call_handler m_funcall;
};
#include "mq_helper.h"
#include <thread>
mq_helper::mq_helper(int mark, int send_code, int recv_code)
: m_mark(mark),
m_msgid(-1),
m_msgtype(0),
m_exit(true),
m_recv_code(recv_code),
m_send_code(send_code),
m_data_recv(msg_st{1, ""}),
m_data_send(msg_st{1, ""})
{
}
mq_helper::~mq_helper()
{
}
bool mq_helper::mq_create()
{
m_msgid = msgget((key_t)m_mark, 0666 | IPC_CREAT);
if (-1 == m_msgid)
{
return false;
}
return true;
}
int mq_helper::mq_write(const char *buf, int size)
{
if (strlen(buf) <= 0)
{
return 0;
}
m_data_send.msg_type = m_send_code;
strcpy(m_data_send.text, buf);
if (-1 == msgsnd(m_msgid, (void *)&m_data_send, size, 0))
{
return 0;
}
return size;
}
int mq_helper::_mq_read(char *buf)
{
if (-1 == msgrcv(m_msgid, (void *)&m_data_recv, BUFSIZ, m_recv_code, 0))
{
buf = NULL;
return 0;
}
strcpy(buf, m_data_recv.text);
return (int)strlen(buf);
}
void _thread_fun(mq_helper *mq)
{
char buf[BUFSIZ] = {0};
while (mq->m_exit)
{
memset(buf, 0, BUFSIZ);
int recv_buf = mq->_mq_read(buf);
mq->m_funcall(recv_buf, buf);
}
}
void mq_helper::mq_set_recv_call(mq_recv_call_handler funcall)
{
m_funcall = funcall;
}
void mq_helper::mq_loop_start()
{
std::thread th(_thread_fun, this);
th.detach();
}
bool mq_helper::mq_delete()
{
if (-1 == msgctl(m_msgid, IPC_RMID, 0))
{
return false;
}
return true;
}
void mq_helper::stop()
{
m_exit = false;
}