消息队列(msg)

来源:互联网 发布:改性沥青离析试验数据 编辑:程序博客网 时间:2024/05/16 06:37

代码:

comm.h:(是一层对于函数接口的封装)

#ifndef _DEBUG_#define _DEBUG_#include <stdio.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/msg.h>#include <string.h>#define _PATH_ "."       //当前路径下#define _PROJ_ID_ 0x6654#define _SIZE_ 3000#define SERVER_TYPE 2#define CLIENT_TYPE 1struct msgbuf{long mtype;        //标识是谁发的消息,也可以标识是给谁发的消息,此处举例是前者char mtext[_SIZE_];//存放发的消息};int creat_queue();//由server创建消息队列,保证创建的是一个全新的消息队列int get_queue();  //client访问消息队列,若不存在,则创建它;若存在,则打开它(不能保证打开的是一个全新的消息队列)int send_msg(int msgqueue_id,int who,char *msg);   //生产消息int recv_msg(int msgqueue_id,int wang,char out[],int out_len); //消费消息int delete_msgqueue(int msgqueue_id);//删除消息队列#endif

comm.c:

#include "msgqueue.h"static int com_creat_queue(int def){key_t key = ftok(_PATH_,_PROJ_ID_);//key标识唯一的消息队列if(key < 0){perror("ftok");return -1;} int msgqueue_id = msgget(key,def);if(msgqueue_id < 0){perror("msgget");//创建消息队列失败return -2;}return msgqueue_id;}int creat_queue(){int def = IPC_CREAT|IPC_EXCL|0666;//IPC_CREAT和IPC_EXCL一起使用保证创建一个全新的消息队列,IPC_EXCL单独使用没有用,必须和IPC_CREAT配合着使用,若消息队列存在,则错误返回;0666是使创建的消息队列的权限是666return com_creat_queue(def);}int get_queue(){int def = IPC_CREAT;//如果该队列不存在,则创建它,否则打开它return com_creat_queue(def);}int send_msg(int msgqueue_id,int who,char *msg){//生产消息struct msgbuf _buf;//_buf存放要发送的消息memset(&_buf,'\0',sizeof(_buf));_buf.mtype = who;//指定是谁发送的消息,也可以指定是谁接受该条消息strncpy(_buf.mtext,msg,sizeof(msg)+1);printf("I say : %s\n",_buf.mtext);return msgsnd(msgqueue_id,&_buf,sizeof(_buf.mtext),0);}int recv_msg(int msgqueue_id,int want,char out[],int out_len){//消费消息struct msgbuf _buf;memset(&_buf,'\0',sizeof(_buf));//将_buf里面的消息删除int ret = msgrcv(msgqueue_id,&_buf,sizeof(_buf.mtext),want,0);// 想要把want的_buf里面的消息删除,成功则返回消息的大小//int ret = msgrcv(msgqueue_id,&_buf,sizeof(_buf),want,0);// 想要把want的_buf里面的消息删除,成功则返回消息的大小if(ret <= -1){perror("msgrcv");return -1;}memset(out,'\0',out_len);//用out将删除的消息保存起来//strncpy(out,_buf.mtext,ret);strcpy(out,_buf.mtext);//printf("%s\n",out);return 0;}int delete_queue(int msgqueue_id){//删除消息队列int ret = msgctl(msgqueue_id,IPC_RMID,NULL);if(ret < 0){perror("msgctl");return -3;}return 0;}
server.c

#include <stdio.h>#include "msgqueue.h"int server(){int msgqueue_id = creat_queue();if(msgqueue_id < 0){perror("server");return -1;}char buf[_SIZE_];while(1){sleep(2);memset(buf,'\0',sizeof(buf));//buf保存消费掉的消息int ret = recv_msg(msgqueue_id,CLIENT_TYPE,buf,sizeof(buf));//server删除从client发送来的消息if(ret == 0){if(strncasecmp(buf,"Quit",4) == 0){printf("client Quit!\n");break;}printf("client say : %s\n",buf);}printf("Please Enter : ");fflush(stdout);memset(buf,'\0',sizeof(buf));gets(buf);//server从标准输出上获取信息并且存放在buf里面send_msg(msgqueue_id,SERVER_TYPE,buf);//经buf里面的消息发送给client}return delete_queue(msgqueue_id);//最后由server删除消息队列}int main(){server();return 0;}

client.c:

#include <stdio.h>#include "msgqueue.h"int client(){int msgqueue_id = get_queue();char buf[_SIZE_];while(1){printf("Please Enter : ");fflush(stdout);memset(buf,'\0',sizeof(buf));//buf保存消费掉的消息gets(buf);//client从标准输出上获取信息并且存放在buf里面send_msg(msgqueue_id,CLIENT_TYPE,buf);//经buf里面的消息发送给serverif(strncasecmp(buf,"Quit",4) == 0){printf("Quit\n");return 0;}sleep(2);memset(buf,'\0',sizeof(buf));//buf保存消费掉的消息int ret = recv_msg(msgqueue_id,SERVER_TYPE,buf,sizeof(buf));//client删除从server发送来的消息if(ret == 0){printf("server say : %s\n",buf);}}}int main(){client();return 0;}

运行结果:

(1)

(2)

(3

)



0 0
原创粉丝点击