代码:
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
)