一、消息队列的定义    

    消息队列能够弥补管道的不足,实现双向交互数据,是一个进程向另一进程发送进程块的方法。与管道不同的是,管道是基于字节流的,消息队列是基于消息的,且消息队列的读取不一定是先进先出。

二、消息队列的创建

    通过函数int messget(key_t key,int msgflg);创建

   key:端口号,可以有 ftok生成。

  msgflg:

    IPC_CRTAT 若果 IPC不存在,则创建一个IPC资源,

    IPC_EXCL:一般和 IPC_CREAT一起使用可以保证所得的对象是新建的,而不是打开已有的。

三、向消息队列读数据

    msgrcv从队列中取的消息

       ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);

    msgsnd将消息放进队列中

       int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);

四、设置消息队列属性

    int msgctl(int msgqid,int cmd,struct msqid_ds *buf);

*** 可以用man 函数名 查看函数***

程序代码:

coom.h

  1 #pragma once
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 #include<sys/types.h>
  6 #include<sys/ipc.h>
  7 #include<sys/msg.h>
  
  8 #define _PATH_ "."
  9 #define _PROCID_ 0x776
 10 #define _SIZE 1024
 11 #define SERVE_MSGTYPE 1
 12 #define CLIECT_MSGTYPE 2
 
 13 typedef struct message
 14 {
 15   long mtype;
 16   char mtext[_SIZE];
 17 }message;
 18 int create_msg(int msg_num);
 19 int drstroy_msg(int msg_id);
 20 int set_msg();
 21 int get_msg();
 22 int msg_send(int msg_id,const char* msg,long type);
 23 int msg_rec(int msg_id ,char buf[],long type);

comm .c

  1 #include"comm.h"
  2  int create_msg(int msg_num)
  3 {
  4   key_t _key=ftok(_PATH_,_PROCID_);
  5   if(_key < 0)
  6   {
  7     perror("ftok");
  8     return -1;
  9   }
 10   int ret= msgget(_key,msg_num);
 11    if(ret < 0)
 12    {
 13     perror("msgget");
 14     return -1;
 15    }
 16  return ret;
 17 }
 18 int drstroy_msg(int msg_id)
 19 {
 20   if(msgctl(msg_id,IPC_RMID,NULL) < 0)
 21   {
 22     perror("msgctl");
 23     return -1;
 24   }else{
 25     printf("remove message_queue\n");
 26     return 0;
 27   }
 28 }
 29 int set_msg()
 30 {
 31   umask(0);
 32   return create_msg(IPC_CREAT |IPC_EXCL |0666);
 33 }
 34 int get_msg()
 35 {
 36     return create_msg(IPC_CREAT);
 37 }
 38 int msg_send(int msg_id,const char* msg,long type)
 39 {
 40   struct message _msg;
 41   _msg.mtype=type;
 42   strcpy(_msg.mtext,msg);
 43   if(msgsnd(msg_id,&_msg,strlen(_msg.mtext),0)< 0)
 44   {
 45     perror("msg_send error");
 46     return -1;
 47   }
 48   return 0;
 49 }
 50 int msg_rec(int msg_id,char buf[],long type)
 51 {
 52   struct message _msg;
 53   memset(_msg.mtext,'\0',_SIZE);
 54   if(msgrcv(msg_id,&_msg,_SIZE,type,0)< 0)
 55   {
 56     perror("msg_receve error");
 57     return -1;
 58   }
 59   strcpy(buf,_msg.mtext);
 60   return 0;
 61 }
 62

client.c

  1 #include"comm.h"
  2 int main()
  3 {
  4  int msg_id=get_msg();
  5  if(msg_id<0)
  6  {
  7   perror("error");
  8   exit(1);
  9  }
 10   char buf[_SIZE];
 11  while(1)
 12  {
 13   fflush(stdout);
 14   printf("please client input: ");
 15   memset(buf,'\0',_SIZE);
 16   fgets (buf,sizeof(buf),stdin);
 17   if(msg_send(msg_id,buf,CLIECT_MSGTYPE)< 0)
 18     {
 19       perror("send fail");
 20       exit(1);
 21     }
 22 
 23   if(msg_rec(msg_id,buf,SERVE_MSGTYPE)<0)
 24     {
 25       perror("recve fail");
 26       exit(1);
 27     }
 28   printf("serve:%s" ,buf);
 29  }
 30   return 0;
 31 }

server.c

  1 #include "comm.h"
  2 int main()
  3 {
  4   int msg_id=set_msg();
  5   if(msg_id<0)
  6   {
  7     perror("mig_id");
  8     exit(1);
  9   }
 10   printf("%d\n",msg_id);
 11   char buf[_SIZE];
 12   while(1)
 13   {
 14      if(msg_rec(msg_id,buf,CLIECT_MSGTYPE)< 0)
 15     {
 16       perror("recve fail");
 17       exit(1);
 18     }
 19     else
 20     {
 21       printf("client :%s",buf);
 22     }
 23     printf("server please input: ");
 24     fflush(stdout);
 25     memset(buf,'\0',_SIZE);
 26     fgets(buf,_SIZE,stdin);
 27     if(msg_send(msg_id,buf,SERVE_MSGTYPE)<0)
 28     {
 29       perror("send fail");
 30       exit(1);
 31     }
 32   }
 33   drstroy_msg(msg_id);
 34   return 0;
 35 }

运行结果:

wKiom1cM4yyiutEVAAG4zXdr9gc424.jpg