一.消息队列
消息队列是一个进程向另一个进程发送一个数据块的方法,所以消息队列是基于消息的,而管道则是基于字节流的。消息队列提供的是进程间的双向通信。
消息队列中的几个原型函数:
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;
}
运行结果:
转载于:https://blog.51cto.com/10541571/1762739