消息队列:操作系统提供缓冲区,提供了一种从一个进程向另一个进程发送一个数据块的方法。消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的。

查看系统消息队列命令:ipcs -q

删除消息队列命令:ipcrm -q 消息id号

相关函数:

原型: 产生消息队列:int msgget(key_t key, int msgflg);

发送消息:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

设置消息队列属性原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

参数:系统定义了 3 种 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID

IPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。
IPC_SET : 该命令来设置消息队列的属性,要设置的属性存储在buf中。
IPC_RMID : 从内核中删除 msqid 标识的消息队列。

//comm.h1#pragmaonce2#include<stdio.h>3#include<stdlib.h>4#include<string.h>5#include<sys/types.h>6#include<unistd.h>7#include<sys/ipc.h>8#include<sys/msg.h>9#define_PATH_"."10#define_PROJ_ID_0x77711#define_BLOCK_SIZE_102412#define_SERVER_MSG_TYPE_113#define_CLIENT_MSG_TYPE_214structmsgbuf15{16longmtype;17charmtext[_BLOCK_SIZE_];18};19staticintcomm_msg_queue(intflag);20intset_msg_queue();21intget_msg_queue();22intmsg_queue_send(intmsg_id,constchar*msg,longtype);23intmsg_queue_recv(intmsg_id,char*msg,longtype);24intdestory_msg_queue(intmsgId);//comm.c1#include"comm.h"2staticintcomm_msg_queue(intflag)3{45key_t_key=ftok(_PATH_,_PROJ_ID_);6if(_key<0)7{8perror("ftok");9return-1;10}11intmsg_id=msgget(_key,flag);12if(msg_id<0)13{14perror("msgget");15return-1;16}17returnmsg_id;18}19intset_msg_queue()20{21umask(0);22returncomm_msg_queue(IPC_CREAT|IPC_EXCL|0666);23}24intget_msg_queue()25{26returncomm_msg_queue(IPC_CREAT);27}28intmsg_queue_send(intmsg_id,constchar*message,longtype)29{30structmsgbufmsg;31msg.mtype=type;32strcpy(msg.mtext,message);33if(msgsnd(msg_id,&msg,strlen(msg.mtext),0)<0)34{35perror("msgsnd");36return-1;37}38return0;39}40intmsg_queue_recv(intmsg_id,char*msg,longtype)41{42structmsgbufret;43memset(ret.mtext,'\0',_BLOCK_SIZE_);44if(msgrcv(msg_id,&ret,_BLOCK_SIZE_-1,type,0)<0)45{46perror("msgrcv");47return-1;48}49strcpy(msg,ret.mtext);50return0;51}52intdestory_msg_queue(intmsg_id)53{54if(msgctl(msg_id,IPC_RMID,NULL)<0)55{56perror("msgctl");57return-1;58}59else60{61printf("removemsg_queue\n");62return0;63}64}//server.c1#include"comm.h"2intmain()3{4intmsgid=set_msg_queue();5if(msgid<0)6{7exit(1);8}9charbuf[_BLOCK_SIZE_];10printf("inputquitendding..\n");11while(1)12{13if(msg_queue_recv(msgid,buf,_CLIENT_MSG_TYPE_)<0)14{15printf("recvfail\n");16exit(1);17}18else19{20if(strcmp("quit",buf)==0)21return0;22printf("client:%s\n",buf);23}24printf("input:");25fflush(stdout);26memset(buf,'\0',_BLOCK_SIZE_);27gets(buf);28if(msg_queue_send(msgid,buf,_SERVER_MSG_TYPE_)<0)29{30printf("sendfail\n");31exit(1);32}33}34destroy(msgid);35return0;36}//client.c1#include"comm.h"2intmain()3{4intmsgid=get_msg_queue();5if(msgid<0)6{7exit(1);8}9charbuf[_BLOCK_SIZE_];10while(1)11{12fflush(stdout);13printf("pleaseinput:");14memset(buf,'\0',_BLOCK_SIZE_);15gets(buf);16if(msg_queue_send(msgid,buf,_CLIENT_MSG_TYPE_)<0)17{18printf("sendfail\n");19exit(1);20}21if(msg_queue_recv(msgid,buf,_SERVER_MSG_TYPE_)<0)22{23printf("recvfail\n");24exit(1);25}26printf("server:%s\n",buf);27}28return0;29}//Makefile的编写1.PHONY:all2all:serverclient3server:server.ccomm.c4gcc-o$@$^5client:client.ccomm.c6gcc-o$@$^7.PHONY:clean8clean:9rm-fserverclient

运行结果: