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

函数:

# 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
 3 #include
 4 #include
 5 #include
 6 #include
 7 #include
 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]$ ./serverplease say#   helloclient: hiplease say#   how are you?    client: fine,and you?please say#   fine[fbl@localhost msg_queue]$ ./clientserver: helloplease say#  hiserver: how are you?please say#  fine,and you?server: fineplease say#