消息队列提供了一种一个进程向另一个进程发送一个数据块的方法。消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的。
消息队列的创建或取得一个已存在的消息队列: int msgget(key_t key,int msgflag);其中的参数: key: 由ftok函数生成; msgflag: IPC_CREAT:如果ipc不存在,则创建一个ipc资源,否则直接打开 IPC_EXCL:本身没有太大的意义,只有和 IPC_CREAT一起使用,可以用来保证所得的对象是新建的,而不是打开已有的对象. 下面是一个用消息队列实现的简单的服务端,客户端简单的收发消息的程序,具体看看他们的用法。client.c文件: #include "comm.h" int main() { int msg_id=get_msg_queue(); if(msg_id<0) { exit(1); } char buf[_BLOCK_SIZE_]; while(1) { fflush(stdout); printf("please input: "); memset(buf,'\0',sizeof(buf)); gets(buf); if(msg_queue_send(msg_id,buf,_CLIENT_ID_)<0) { printf("sned fail\n"); exit(1); } memset(buf,'\0',sizeof(buf)); if(msg_queue_recv(msg_id,_SERVER_ID_,buf)<0) { printf("recv fail\n"); exit(1); } else { if(strcmp(buf,"quie")==0) { printf("server quit\n"); break; } printf("server: %s\n",buf); } } return 0;} server.c:文件: #include "comm.h" int main() { int queue_id=creat_msg_queue(); if(queue_id<0) { exit(1); } char buf[_BLOCK_SIZE_]; while(1) { memset(buf,'\0',sizeof(buf)); if(msg_queue_recv(queue_id,_CLIENT_ID_,buf)<0) { printf("recv fail\n"); exit(1); } else { if(strcmp(buf,"quit")==0) { printf("client quit\n"); break; } printf("client: %s\n",buf); } printf("please input: "); fflush(stdout); memset(buf,'\0',sizeof(buf)); gets(buf); if(msg_queue_send(queue_id,buf,_SERVER_ID_)<0) { printf("send fail\n"); exit(1); } } destroy_msg_queue(queue_id); return 0; } comm.h文件: #pragma once #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <string.h> #include <unistd.h> #define _PATH_ "." #define _PROJ_ID_ 0x5666 #define _BLOCK_SIZE_ 1024 #define _SERVER_ID_ 1 #define _CLIENT_ID_ 2 struct msgbuf { long mtype; char mtext[_BLOCK_SIZE_]; }; int comm_msg_queue(int flag); int creat_msg_queue(); int msg_queue_recv(int msg_id,int recv_type,char buf[]); int destroy_msg_queue(int msg_id); int msg_queue_send(int msg_id,const char* message,long type); int get_msg_queue(); comm.c文件: #include "comm.h" int comm_msg_queue(int flag) { key_t _key=ftok(_PATH_,_PROJ_ID_); if(_key<0) { perror("ftok"); return -1; } int msg_id=msgget(_key,flag); if(msg_id<0) { perror("msgget"); return -1; } return msg_id; } int creat_msg_queue() { umask(0); return comm_msg_queue(IPC_CREAT |IPC_EXCL |0666); } int get_msg_queue() { return comm_msg_queue(IPC_CREAT); } int msg_queue_send(int msg_id,const char* message,long type) { struct msgbuf msg; msg.mtype=type; strcpy(msg.mtext,message); if(msgsnd(msg_id,&msg,sizeof(msg.mtext),0)<0) { perror("msgsnd"); return -1; } return 0; } int msg_queue_recv(int msg_id,int recv_type,char buf[]) { struct msgbuf msg; if(msgrcv(msg_id,&msg,sizeof(msg.mtext),recv_type,0)<0) { perror("msgrcv"); return -1; } strcpy(buf,msg.mtext); return 0; } int destroy_msg_queue(int msg_id) { if(msgctl(msg_id,IPC_RMID,NULL)<0) { perror("msgct"); return -1; } else { printf("remove success\n"); } return 0; }Makefile文件的编写: .PHONY:all all:client server client:client.c comm.c gcc -o $@ $^ server:server.c comm.c gcc -o $@ $^ .PHONY:clean clean: rm -f client server上面程序的运行结果: 从而实现了简单的收发消息的功能。