消息队列提供了一个进程向另一个进程发送数据块的方法。消息队列的结构
linux为参与消息传递的进程提供msgsnd来发送消息,提供msgrcv来接受消息
msgsnd
msgrcv
消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的。
下面是代码实现
comm.h
#ifndef _COMM_#define _COMM_#include<stdio.h>#include<sys/types.h>#include<sys/ipc.h>#include<fcntl.h>#include<sys/msg.h>#include<string.h>#define PATHNAME "."#define PROJID 0x6666#define MYSIZE 128#define SERVER_TYPE 1#define CLIENT_TYPE 2struct msgbuf{long mtype;char mtext[MYSIZE];};int creatMsgQueue();int getMsgQUeue();int sendMessage(int msg_id,long type,const char* msg);int recvMessage(int msg_id,int type,char out[]);int destoryMsgQueue(int id);#endifcomm.c#include"comm.h"static int commMsgQueue(int flag){key_t _k=ftok(PATHNAME,PROJID);if(_k<0) { perror("ftok"); return -1; } int msg_id=msgget(_k,flag); if(msg_id<0) { perror("msgget");return -2; } return msg_id;}int creatMsgQueue(){return commMsgQueue(IPC_CREAT|IPC_EXCL|0666);}int getMsgQueue(){return commMsgQueue(IPC_CREAT);}int sendMessage(int msg_id,long type,const char* msg){struct msgbuf buf;buf.mtype=type;strcpy(buf.mtext,msg);int ret=msgsnd(msg_id,&buf,sizeof(buf.mtext),0);printf("Debug ret:%d",ret);if(ret<0){perror("msgsnd");printf("Debug:CLient msgsnd/n");return -1;}return 0;}int recvMessage(int msg_id,int type,char out[]){struct msgbuf buf; int size=msgrcv(msg_id,&buf,sizeof(buf.mtext),type,0); if(size>0) { buf.mtext[size]='/0'; printf("DEBUE:%s SIZE:%d/n",buf.mtext,size); strncpy(out,buf.mtext,size); return 0; } perror("msgrcv"); return -1;}int destoryMsgQueue(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 msg_id=creatMsgQueue(); char buf[2*MYSIZE]; while(1) { if(recvMessage(msg_id,CLIENT_TYPE, buf)<0) { break; } printf("client# %s/n",buf); if(sendMessage(msg_id,SERVER_TYPE,buf)<0) { break; } printf("server# %s/n",buf); } destoryMsgQueue(msg_id);return 0;}client.c#include"comm.h"int main(){ int msg_id=getMsgQueue(); char buf[MYSIZE]; char out[2*MYSIZE]; while(1) { printf("please enter: "); fflush(stdout); ssize_t _s=read(0,buf,sizeof(buf)-1); if(_s>0) { buf[_s]='/0'; sendMessage(msg_id,CLIENT_TYPE,buf); } if(recvMessage(msg_id,SERVER_TYPE,out)<0) { break; } printf("server echo# %s/n",out); }return 0;}下面是本项目的Makefilecli=clientser=servercc=gccserSrc=comm.c server.ccliSrc=comm.c client.c.PHONY:allall:$(cli) $(ser)$(cli):$(cliSrc) $(cc) -o $@ $^$(ser):$(serSrc) $(cc) -o $@ $^.PHONY:cleanclean: rm -f $(cli) $(ser)传送之前
传送之后
新闻热点
疑难解答