消息队列(报文队列):两个进程间通过发送数据块的形式进行通信。一个进程把需要发送的消息通过一个函数发送到消息队列中,另一个进程再从消息队列中读取该消息。

函数:

# include <sys/types.h>

# include <sys/ipc.h>

key_t ftok(const char *pathname, int proj_id); //生成下面函数的key.可认为是一个端口号

int msgget(key_t key, int msgflg);//创建消息队列,返回消息队列的 msgid

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);//接收消息队    列中的消息,把接收到的内容写入msgp中。

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//将msgp中的内容读入消息    队列中。

struct msgstru 

{

  long mtype; //大于0 

  char mtext[用户指定大小];

};

msgflg:

 1.IPC_CREAT:如果没有就创建,有就打开。

 2.IPC_EXCL:本身没多大意义

 3.IPC_CREAT|IPC_EXCL:如果没有就创建,有就出错返回,保证每一次创建都是全新的。

特点:

  1. 双向通信。 

  2. 消息队列是随内核持续的。只有在内核重启或显示删除一个消息队列时,才会被真正删除。

  3. 消息队列是基于消息的。且消息队列的读取不一定是先入先出。

  4. 每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节

  5. 每个消息的最大长度是有上限的(MSGMAX),每个消息队列的总的字节数是有上限的(MSGMNB),系统上消息队列的总数也有一个上限(MSGMNI)。

  6. 可避免同步和阻塞问题。

 comm.h
 1 #pragma once
 2 #include<stdio.h>
 3 #include<sys/types.h>
 4 #include<sys/ipc.h>
 5 #include<sys/msg.h>
 6 #include<stdlib.h>
 7 #include<string.h>
 8 
 9 #define _PATH_ "."
 10 #define _PROJ_ID_ 0x7777
 11 #define _MAX_NUM_ 256
 12 #define _SERVER_ 1
 13 #define _CLIENT_ 2
 14 struct msgstru
 15 {
 16     long mtype;
 17     char mtext[_MAX_NUM_];
 18 };
 19 int creat_msg_queue();
 20 int get_msg_queue();
 21 int send_msg(int msgid,char* text,long type);
 22 int recv_msg(int msgid,char* text,long type);
 23 int distroy_msg_queue(int msgid);
 
 comm.c
 1 #include"comm.h"
 2 static int comm_msg_queue(int flag)
 3 {
 4     key_t key = ftok(_PATH_,_PROJ_ID_);
 5     if(key == -1)
 6     {
 7         perror("ftok");
 8         return -1;
 9     }
 10     int msgid = msgget(key,flag);
 11     if(msgid==-1)
 12     {
 13         perror("msgget");
 14         return -1;
 15     }
 16     return msgid;
 17 }
 18 int creat_msg_queue()
 19 {
 20     return comm_msg_queue(IPC_CREAT|IPC_EXCL|0666);
 21 }
 22 int get_msg_queue()
 23 {
 24     return comm_msg_queue(IPC_CREAT);
 25 }
 26 int send_msg(int msgid,char *text,long type)
 27 {
 28     struct msgstru msg;
 29     msg.mtype = type;
 30     strcpy(msg.mtext,text);
 31     if(msgsnd(msgid,&msg,sizeof(msg.mtext),0)==-1)
 32     {
 33         perror("msgsnd");
 34         return -1;
 35     }
 36     return 0;
 37 }
 38 int recv_msg(int msgid,char *text,long type)
 39 {
 40     struct msgstru msg;
 41     memset(msg.mtext,'\0',sizeof(msg.mtext));
 42     if(msgrcv(msgid,&msg,sizeof(msg.mtext),type,0)==-1)
 43     {
 44         perror("msgrcv");
 45         return -1;
 46     }
 47     strcpy(text,msg.mtext);
 48     return 0;
 49 
 50 }
 51 int distroy_msg_queue(int msgid)
 52 {
 53     if(msgctl(msgid,IPC_RMID,NULL)==-1)
 54     {
 55         perror("msgctl");
 56         return -1;
 57     }
 58     return 0;
 59 }
 
 server.c
  1 #include"comm.h"
  2 int main()
  3 {   
  4     int msgid = creat_msg_queue();
  5     if(msgid == -1)
  6     {
  7         return -1;
  8     }
  9     char buf[_MAX_NUM_];
 10     while(1)
 11     {   
 12         memset(buf,'\0',sizeof(buf));
 13         fflush(stdout);
 14         printf("please say#   ");
 15         gets(buf);
 16         if(send_msg(msgid,buf,_SERVER_)==-1)
 17         {
 18             return -1;
 19         }   
 20         if(recv_msg(msgid,buf,_CLIENT_)==-1)
 21         {
 22             return -1;
 23         }
 24         printf("client: %s\n",buf);
 25     }
 26     distroy_msg_queue(msgid);
 27     return 0;
 28 }
 
 client.c
  1 #include"comm.h"
  2 int main()
  3 {   
  4     int msgid = get_msg_queue();
  5     if(msgid==-1)
  6     {   
  7         return -1;
  8     }
  9     char buf[_MAX_NUM_];
 10     while(1)
 11     {   
 12         if(recv_msg(msgid,buf,_SERVER_)<0)
 13         {   
 14             return -1;
 15         }
 16         printf("server: %s\n",buf);
 17         fflush(stdout);
 18         memset(buf,'\0',sizeof(buf));
 19         printf("please say#  ");
 20         gets(buf);
 21         if(send_msg(msgid,buf,_CLIENT_)==-1)
 22         {   
 23             return -1;
 24         }
 25     }
 26     return 0;
 27 }
 
 结果:
 [fbl@localhost msg_queue]$ ./server
please say#   hello
client: hi
please say#   how are you?    
client: fine,and you?
please say#   fine

[fbl@localhost msg_queue]$ ./client
server: hello
please say#  hi
server: how are you?
please say#  fine,and you?
server: fine
please say#