消息队列
提供从一个进程向另一哥进程发送一块数据的方法
每个数据块都被认为有一个类型,接收者进程收到的数据块可以有不同类型值
消息队列的最大长度,总字节数,消息队列的数都有上限
comm.h
#pragma once
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#define PATHNAME "."
#define PROJ_ID 0X6666
#define SERVER_TYPE 1
#define CLIENT_TYPE 2
struct msgbuf{ //消息结构
long mtype;
char mtext[1024];
};
int createMsgQueue(); //创建消息队列函数
int getMsgQueue(); //访问消息队列函数
int destroyMsgQueue(int msgid); //销毁消息队列函数
int sendMsg(int msgid, int who ,char *msg); //发送消息
int recvMsg(int msgid, int recvType, char out[]); //接受消息
comm.c
#include"comm.h"
static int commMsgQueue(int flags) //控制消息队列函数
{
key_t _key=ftok(PATHNAME,PROJ_ID); //创建消息队列获取ID
if(_key<0)
{
perror("ftok"); //获取ID失败
return -1 ;
}
int msgid=msgget(_key,flags);//创建和访问一个消息队列
//int msgid=msgget(_key,IPC_CREAT|IPC_EXCL);
if(msgid<0)
{
perror("msgget"); //创建或者访问失败
}
return msgid ; //创建成功返回标识码
}
int createMsgQueue() //创建消息队列函数
{
return commMsgQueue(IPC_CREAT|IPC_EXCL|0666); //调整队列权限
}
int getMsgQueue() //访问消息队列
{
return commMsgQueue(IPC_CREAT);
}
int destroyMsgQueue(int msgid) //销毁消息队列函数
{
int m=msgctl(msgid,IPC_RMID,NULL) ; //删除消息队列
if(m<0)
{
perror("msgctl"); //删除失败
return -1 ;
}
//删除成功
return 0;
}
int sendMsg(int msgid, int who ,char*msg) //发送消息
{
struct msgbuf buf ;
buf.mtype=who;
strcpy(buf.mtext,msg); //把消息拷贝到buf.mtext中
if(msgsnd(msgid,(void*)&buf,sizeof(buf.mtext),0)<0)
{
perror("msgsnd"); //发送失败
return -1;
}
//发送成功
return 0;
}
int recvMsg(int msgid, int recvType ,char out[]) //接收消息
{
struct msgbuf buf ;
if(msgrecv(msgid,(void*)&buf,sizeof(buf.mtext), recvType ,0)<0)
{ //接收失败
perror("msgrecv");
return -1 ;
}
//接收成功
strcpy(out,buf.mtext); 拷贝消息内容到out中
return 0 ;
}
服务端server.c
#include"comm.h"
int main()
{
int msgid=createMsgQueue(); //创建消息队列
char buf[1024];
while(1)
{
buf[0]=0;
recvMsg(msgid,CLIENT_TYPE,buf); //接收消息
printf("client# %s\n",buf); //打印接收到的消息
printf("Please enter# ");
fflush(stdout); //刷新
ssize_t s=read(0,buf,sizeof(buf)); //从当前读取信息到buf中
if(s>0) //读取成功
{
buf[s-1]=0;
sendMsg(msgid,SERVER_TYPE,buf); //服务器发送消息
printf("send done,wait recv...\n");
}
}
destroyMsgQueue(msgid); //调用销毁消息队列函数
return 0;
}
客户端client.c
#include"comm.h"
int main()
{
int msgid=getMsgQueue(); //创建消息队列
char buf[1024];
while(1)
{
buf[0]=0;
printf("please enter# ");
fflush(stdout); //刷新
ssize_t s=read(0,buf,sizeof(buf)); //把内容读取到buf中
if(s>0)
{ //读取成功
buf[s-1]=0;
sendMsg(msgid,CLIENT_TYPE,buf); //客户端发送消息到buf中
printf("send done ,wait recv...\n");
}
recvMsg(msgid,SERVER_TYPE,buf);//接收服务端发来的消息到buf中
printf("server# %s\n",buf); //打印收到的消息
}
return 0 ;
}