消息队列(msg)

代码:

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 1

struct 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是使创建的消息队列的权限是666
	return 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里面的消息发送给server
		if(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

)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值