一. 消息队列的通信原理
消息队列放在链表当中,链表中每一个消息放在结构体当中,
(链表中每一项都是一个结构体)。
AB使用同一个队列进行通讯
消息队列按照消息的类型进行读取
二、在Linux中使用消息队列
(1)创建或打开消息队列函数
int msgget(key_t, key, int msgflg);
(2)添加消息函数
int msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);如果调用成功,消息数据的一分副本将被放到消息队列中,并返回0,失败时返回-1.
(3)从一个消息队列中获取消息:
int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);调用成功时,该函数返回放到接收缓存区中的字节数,消息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除消息队列中的对应消息。失败时返回-1.
(4)消息队列控制函数:
int msgctl(int msgid, int command, struct msgid_ds *buf);
command是将要采取的动作,它可以取3个值,
IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。
IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值
IPC_RMID:删除消息队列
buf是指向msgid_ds结构的指针,它指向消息队列模式和访问权限的结构。msgid_ds结构至少包括以下成员:
struct msgid_ds { uid_t shm_perm.uid; uid_t shm_perm.gid; mode_t shm_perm.mode; };
成功时返回0,失败时返回-1.
1.发送消息:
//文件msgsend.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdio.h>
#include<string.h>
// int msgget(key_t key, int msgflg);
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// size_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf{
long mtype;
char mtext[128];
};
int main()
{
struct msgbuf sendBuf = {888,"this is message from quen"};
struct msgbuf readBuf;
int msgId = msgget(0x1235,IPC_CREAT|0777);
if(msgId == -1){
printf("get que failuer\n");
}
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);
printf("send over\n");
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);
printf("return from get:%s\n",readBuf.mtext);
return 0;
}
接收消息:
//文件msgGet.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdio.h>
#include<string.h>
// int msgget(key_t key, int msgflg);
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// size_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf{
long mtype;
char mtext[128];
};
int main()
{
struct msgbuf readBuf;
int msgId = msgget(0x1235,IPC_CREAT|0777);
if(msgId == -1){
printf("get que failuer\n");
}
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),888,0);
printf("read from que:%s\n",readBuf.mtext);
struct msgbuf sendBuf = {988,"thank you for reach"};
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);
return 0;
}
2.发送消息:
//文件msgSend2.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdio.h>
#include<string.h>
// int msgget(key_t key, int msgflg);
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// size_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf{
long mtype;
char mtext[128];
};
int main()
{
struct msgbuf sendBuf = {888,"this is message from quen"};
struct msgbuf readBuf;
key_t key;
key = ftok(".",'z');
printf("key=%x\n",key);
int msgId = msgget(key,IPC_CREAT|0777);
if(msgId == -1){
printf("get que failuer\n");
}
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);
printf("send over\n");
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),988,0);
printf("return from get:%s\n",readBuf.mtext);
msgctl(msgId,&sendBuf,strlen(sendBuf.mtext),0);
return 0;
}
接收消息:
//文件msgGet2.c
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include<stdio.h>
#include<string.h>
// int msgget(key_t key, int msgflg);
// int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
// size_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
struct msgbuf{
long mtype;
char mtext[128];
};
int main()
{
struct msgbuf readBuf;
key_t key;
key = ftok(".",'z');
printf("key=%x\n",key);
int msgId = msgget(key,IPC_CREAT|0777);
if(msgId == -1){
printf("get que failuer\n");
}
msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),888,0);
printf("read from que:%s\n",readBuf.mtext);
struct msgbuf sendBuf = {988,"thank you for reach"};
msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);
msgctl(msgId,&sendBuf,strlen(sendBuf.mtext),0);
return 0;
}
运行结果:
CLC@Embed_Learn:~$ ./send
key=7a055bb6
send over
return from get:thank you for reach
CLC@Embed_Learn:~$ ./get
key=7a055bb6
read from que:this is message from quen
版权声明:本文为m0_60970579原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。