消息队列
- 本质:内核中提供的一种链表,提供了一个进程向另一个进程发送一块数据块的方法
消息队列的常见函数以及解析,参考以下这个博主的博客,有相关的总结
-https://blog.csdn.net/xiaohuima_dong/article/details/44773815用消息队列实现进程间的通信
include"comm.h"
int main()
{
int msgid=createMsgQueue(); //创建消息队列
char buf[1024];
while(1)
{
buf[0]=0;
recvMsg(msgid,CLIENT_TYPE,buf); //接收消息,来自客户端的,到buf中
printf("client# %s\n",buf); //打印存放在buf中收到的数据
printf("Please enter# "); //服务器准备向客户端发送数据
fflush(stdout);
ssize_t s=read(0,buf,sizeof(buf)); //从当前(0表示当前)读取数据到buf中
if(s>0) //读取成功
{
buf[s-1]=0;
sendMsg(msgid,SERVER_TYPE,buf); //将数据发送
printf("send done,wait recv...\n");
}
}
destroyMsgQueue(msgid);
return 0;
}
//客户端
#include"comm.h"
int main()
{
int msgid=getMsgQueue();
char buf[1024];
while(1)
{
buf[0]=0;
printf("please enter# ");
fflush(stdout);
ssize_t s=read(0,buf,sizeof(buf)); //把当前的内容读取到buf中
if(s>0)
{ //读取成功
buf[s-1]=0;
sendMsg(msgid,CLIENT_TYPE,buf); //客户端发送消息给服务器,存放到buf中
printf("send done ,wait recv...\n");
}
recvMsg(msgid,SERVER_TYPE,buf);//接收服务端发来的数据,到buf中
printf("server# %s\n",buf);
}
return 0 ;
}
//函数的实现
#include"comm.h"
static int commMsgQueue(int flags) //控制消息队列函数
{
key_t _key=ftok(PATHNAME,PROJ_ID); //获取消息队列的名字,也就是ID
if(_key<0)
{
perror("ftok");
return -1 ;
}
int msgid=msgget(_key,flags);//创建和访问一个消息队列
//int msgid=msgget(_key,IPC_CREAT|IPC_EXCL);//权限
if(msgid<0)
{
perror("msgget"); //创建或者访问失败
}
return msgid ; //创建成功返回标识码
}
int createMsgQueue() //创建消息队列函数
{
return commMsgQueue(IPC_CREAT|IPC_EXCL|0666); //调整队列权限
}
int getMsgQueue() //访问消息队列
{
return commMsgQueue(IPC_CREAT);
}
int destroyMsgQueue(int msgid)
{
int m=msgctl(msgid,IPC_RMID,NULL) ;
if(m<0)
{
perror("msgctl");
return -1 ;
}
//删除成功
return 0;
}
int sendMsg(int msgid, int who ,char*msg) //发送消息
{
struct msgbuf buf ;
buf.mtype=who; //发送数据的优先级
strcpy(buf.mtext,msg); //把消息拷贝到buf.mtext中
if(msgsnd(msgid,(void*)&buf,sizeof(buf.mtext),0)<0)
{
perror("msgsnd");
return -1;
}
return 0;
}
int recvMsg(int msgid, int recvType ,char out[]) //接收消息
{
struct msgbuf buf ;
if(msgrecv(msgid,(void*)&buf,sizeof(buf.mtext), recvType ,0)<0)
{
perror("msgrecv");
return -1 ;
}
//接收成功
strcpy(out,buf.mtext); 拷贝消息内容到out中
return 0 ;
}
//头文件
pragma once
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#define PATHNAME "."
#define PROJ_ID 0X6666
#define SERVER_TYPE 1
#define CLIENT_TYPE 2
struct msgbuf{
long mtype;//优先级
char mtext[1024];//不仅仅装字符串的缓存区
};
int createMsgQueue(); //创建消息队列函数
int getMsgQueue(); //访问消息队列函数
int destroyMsgQueue(int msgid); //销毁消息队列函数
int sendMsg(int msgid, int who ,char *msg); //发送消息
int recvMsg(int msgid, int recvType, char out[]); //接受消息
消息队列用于任意进程之间,全双工通信
面向数据报(无论报文多长不拆分不合并,一次发送一个)
- 生命周期随内核:直到显示删除
@localhost ~]$ ipcrm -q 32768
如图,执行命令后就会不见