本文基于消息队列实现数据接收和发送功能,通过新建两个线程分别实现消息队列的数据接收和消息队列的数据发送,其中消息队列的数据接收,通过二维队列实现数据缓存;消息队列的数据发送,通过从二维队列(数据缓存)读取数据。具体程序例程如下所示:
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <dirent.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include "app_systemlog.h"
#include "app_queue.h"
#define MSGMAX 8192
typedef struct msgbuf {
long mtype; /* message type, must be > 0 */
unsigned char mbuffer[MSGMAX]; /* message data */
}msgq_t;
const key_t rcvmsg_key = 1234;
const key_t sendmsg_key = 4321;
/******************************************************************************
*FUNCATION NAME : void *messageQueue_RecvServer(void *argc)
*CREATE DATE : 2022-10-12
*CREATE BY : LSL
*FUNCTION : 消息队列接收线程
*MODIFY DATE :
*INPUT :
*OUTPUT :
*RETURN :
*OTHERS :
******************************************************************************/
void *messageQueue_RecvServer(void *argc)
{
int msgid=-1, recv_size;
int ret;
// int run_flag = 1;
long int msgtype = 0;
msgq_t rcv_data;
platform_write(LINUX_DEBUG,"======messageQueue_RecvServer is OK======\n");
msgid = msgget(rcvmsg_key, 0666 | IPC_CREAT);
if(msgid == -1)
{
printf("msgget failed with error\n");
return ((void *)-1);
}
while(1)
{
bzero(&rcv_data,BUFSIZ);
recv_size = msgrcv(msgid, &rcv_data, MSGMAX, msgtype, 0);
if(recv_size>0)
{
//printf("recv queue type %ld, data: %s,the num is %d\n", rcv_data.mtype, rcv_data.mbuffer,recv_size);
write_MessageQueue(&msgRevDataQueue, rcv_data.mbuffer, recv_size);
//write_MessageQueue(&msgSendDataQueue, rcv_data.mbuffer, recv_size);//测试使用,通过
}
usleep(10);
}
ret = msgctl(msgid, IPC_RMID, 0);
if(ret == -1)
{
printf("msgctl failed with error\n");
return ((void *)-1);
}
return ((void *)0);
}
/******************************************************************************
*FUNCATION NAME : void *messageQueue_SendServer(void *argc)
*CREATE DATE : 2022-10-12
*CREATE BY : LSL
*FUNCTION : 消息队列发送线程
*MODIFY DATE :
*INPUT :
*OUTPUT :
*RETURN :
*OTHERS :
******************************************************************************/
void *messageQueue_SendServer(void *argc)
{
unsigned char r_buf[MSGMAX];
int recv = -1,ret;
int msgid=-1;
//int len = 0,totalsize=0;
msgq_t send_data;
long int msgtype = 1;
platform_write(LINUX_DEBUG,"======socket_UdpSendServer is OK======\n");
msgid = msgget(sendmsg_key, 0666 | IPC_CREAT);
if (msgid == -1)
{
printf("msgget failed with error\n");
return ((void *)-1);
}
send_data.mtype = msgtype;
while(1)
{
memset(r_buf, 0, sizeof(r_buf));
//recv=read_Queue_Chars(&udpDataQueue, r_buf, 1024);
//首先读取帧头,判断是否是通讯帧,如果是通讯帧,再读取帧数据
recv=read_MessageQueue(&msgSendDataQueue, r_buf);
if(recv>0)
{
memcpy(send_data.mbuffer,r_buf,recv);
ret=msgsnd(msgid, &send_data,recv,0);//发送消息队列
//len =send(tcp_data_fd, buffer, (size-totalsize), 0);//
///printf("msgsnd len is %d,the recv is %d\n",len,recv);
if(ret < 0)
{
printf("msgsnd failed with error\n");
break;
}
}
usleep(10);//10us延时
}
return ((void *)0);
}
注意事项:
1、通过两个不同的key来区分接收消息队列和发送消息队列;
2、接收消息队列通过阻塞的方式判断是否收到消息,如有收到,存入接收队列缓存;
3、发送消息队列通过无限循环判断发送缓存是否有数据,如果有数据,触发1次消息队列发送;
4、以上程序源码在嵌入式linux系统、ubuntu系统上均实测可用,以上程序仅是全部程序的部分,因此不能直接使用,仅供参考。