您的位置:首页 > 其它

进程间通信 :消息队列的实现

2016-04-11 20:14 405 查看
一.消息队列

消息队列是一个进程向另一个进程发送一个数据块的方法,所以消息队列是基于消息的,而管道则是基于字节流的。消息队列提供的是进程间的双向通信。
消息队列中的几个原型函数:
1.获取消息信息:int msgget(key_t key,int msgflag);key 是用ftok()函数创建的

2.接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
3.发送消息:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
4.销毁消息信息:int msfctl(int msgid)
查看key值命令:ipcs -q
删除key值命令:ipcs -q key值
//comm.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define _PATH_ "."  //路径
#define _PROJ_ID_ 0x7777
#define _BLOCK_SIZE_ 1024
#define _CLIENT_TYPE_ 1
#define _SERVER_TYPE_ 2
struct msgBuf  //定义一个消息结构体
{
long mtype; //消息类型
char mtext[_BLOCK_SIZE_];
};

static int creat_msg_queue();
int get_msg_queue();
int send_msg_queue(int msg_id,const char*info,long type);
int recv_msg_queue(int msg_id,char info[],long type);
int destroy_msg_queue(int msg_id);

//comm.c

#include"comm.h"

int get_msg_queue()
{
return creat_msg_queue();
}

static int creat_msg_queue()
{
key_t key=ftok(_PATH_,_PROJ_ID_);
if(key<0)
{
perror("ftok");
return -1;
}
int msg_id=msgget(key,IPC_CREAT);
if(msg_id<0)
{
perror("msgget");
return -1;
}

return msg_id;
}

int send_msg_queue(int msg_id,const char*info,long type)//将要发送的消息存入mtext中
{
struct msgBuf msg;
msg.mtype=type;
memset(msg.mtext,'\0',sizeof(msg.mtext));
strcpy(msg.mtext,info);
if(msgsnd(msg_id,&msg,sizeof(msg.mtext),0)<0)
{
perror("msgsnd");
return -1;

}
return 0;
}

int recv_msg_queue(int msg_id,char* info,long type)//将mtext中的消息拿出放入info中
{
struct msgBuf msg;
if(msgrcv(msg_id,&msg,sizeof(msg.mtext),type,0)<0)
{
perror("msgrcv");
return -1;
}
strcpy(info,msg.mtext);
return 0;
}

int destroy_msg_queue(int msg_id)
{
if(msgctl(msg_id,IPC_RMID,NULL)<0)
{
perror("msgctl");
return -1;
}
return 0;

}
//server.c  先发送后接收

#include"comm.h"

int main()
{
int msgid=get_msg_queue();
if(msgid<0)
{
exit(1);
}
char info[_BLOCK_SIZE_];

while(1)
{
memset(info,'\0',sizeof(info));
printf("please input:");
fflush(stdout);
gets(info);
if(send_msg_queue(msgid,info,_SERVER_TYPE_)<0)
{
printf("send  information failed\n");
exit(1);
}
if(recv_msg_queue(msgid,info,_CLIENT_TYPE_)<0)
{
printf("recieve information failed\n");
exit(1);
}
printf("client:%s\n",info);
}
destroy(msgid);
return 0;
}

//client.c 先接收后发送
#include"comm.h"
int main()
{
int msgid=get_msg_queue();
if(msgid<0)
{
exit(1);
}
char info[_BLOCK_SIZE_];
memset(info,'\0',sizeof(info));
printf("when input stop endding...\n");
while(1)
{
if(recv_msg_queue(msgid,info,_SERVER_TYPE_)<0)
{
printf("recieve information failed\n");
exit(1);
}
else
{

if(strcmp("stop",info)==0)
{
return 0;
}
printf("server :%s\n",info);
}

printf("please input:");
fflush(stdout);
gets(info);
if(send_msg_queue(msgid,info,_CLIENT_TYPE_)<0)
{
printf("send information failed\n");
exit(1);
}
}
destroy(msgid);
return 0;

}
运行结果:


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  消息队列