进程间通信:消息队列实现双向通信

消息队列:操作系统提供缓冲区,提供了一种从一个进程向另一个进程发送一个数据块的方法。消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的。

查看系统消息队列命令:ipcs -q

删除消息队列命令:ipcrm -q 消息id号

相关函数:

原型: 产生消息队列:int msgget(key_t key, int msgflg);

发送消息:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

设置消息队列属性原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

参数:系统定义了 3 种 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID

IPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。
IPC_SET : 该命令来设置消息队列的属性,要设置的属性存储在buf中。
IPC_RMID : 从内核中删除 msqid 标识的消息队列。

  //comm.h
  1 #pragma once
  2 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<string.h>
  5 #include<sys/types.h>
  6 #include<unistd.h>
  7 #include<sys/ipc.h>
  8 #include<sys/msg.h>
  9 #define _PATH_ "."
 10 #define _PROJ_ID_ 0x777
 11 #define _BLOCK_SIZE_ 1024
 12 #define _SERVER_MSG_TYPE_ 1
 13 #define _CLIENT_MSG_TYPE_ 2
 14 struct msgbuf
 15 {
 16     long mtype;
 17     char mtext[_BLOCK_SIZE_];
 18 };
 19 static int comm_msg_queue(int flag);
 20 int set_msg_queue();
 21 int get_msg_queue();
 22 int msg_queue_send(int msg_id,const char* msg,long type);
 23 int msg_queue_recv(int msg_id,char* msg,long type);
 //comm.c
  1 #include"comm.h"
  2 static int comm_msg_queue(int flag)
  3 {
  4 
  5     key_t _key=ftok(_PATH_,_PROJ_ID_);
  6     if(_key<0)
  7     {
  8         perror("ftok");
  9         return -1;
 10     }   
 11     int msg_id=msgget(_key,flag);
 12     if(msg_id<0)
 13     {
 14         perror("msgget");
 15         return -1;
 16     }   
 17     return msg_id;
 18 }   
 19 int set_msg_queue()
 20 {
 21     umask(0);
 22     return comm_msg_queue(IPC_CREAT|IPC_EXCL|0666);
 23 }   
 24 int get_msg_queue()
 25 {
 26     return comm_msg_queue(IPC_CREAT);
 27 }   
 28 int msg_queue_send(int msg_id,const char* message,long type)
 29 {
 30     struct msgbuf msg;
 31     msg.mtype=type;
 32     strcpy(msg.mtext,message);
 33     if(msgsnd(msg_id,&msg,strlen(msg.mtext),0)<0)
 34     {
 35         perror("msgsnd");
 36         return -1;
 37     }   
 38     return 0;
 //server.c
  1 #include"comm.h"
  2 int main()
  3 {
  4     int msgid=set_msg_queue();
  5     if(msgid<0)
  6     {
  7         exit(1);
  8     }
  9     char buf[_BLOCK_SIZE_];
 10     printf("input quit endding..\n");
 11     while(1)
 12     {
 13         if(msg_queue_recv(msgid,buf,_CLIENT_MSG_TYPE_)<0)
 14         {
 15             printf("recv fail\n");
 16             exit(1);
 17         }
 18         else
 19         {
 20             if(strcmp("quit",buf)==0)
 21                 return 0;
 22             printf("client:%s\n",buf);
 23         }
 24         printf("input:");
 25         fflush(stdout);
 26         memset(buf,‘\0‘,_BLOCK_SIZE_);
 27         gets(buf);
 28         if(msg_queue_send(msgid,buf,_SERVER_MSG_TYPE_)<0)
 29         {
 30             printf("send fail\n");
 31             exit(1);
 32         }
 33     }
 34     destroy(msgid);
 35     return 0;
 36 }
 //client.c
  1 #include"comm.h"
  2 int main()
  3 {
  4     int msgid=get_msg_queue();
  5     if(msgid<0)
  6     {
  7         exit(1);
  8     }
  9     char buf[_BLOCK_SIZE_];
 10     while(1)
 11     {
 12         fflush(stdout);
 13         printf("please input:");
 14         memset(buf,‘\0‘,_BLOCK_SIZE_);
 15         gets(buf);
 16         if(msg_queue_send(msgid,buf,_CLIENT_MSG_TYPE_)<0)
 17         {
 18             printf("send fail\n");
 19             exit(1);
 20         }
 21         if(msg_queue_recv(msgid,buf,_SERVER_MSG_TYPE_)<0)
 22         {
 23             printf("recv fail\n");
 24             exit(1);
 25         }
 26         printf("server:%s\n",buf);
 27     }
 28     return 0;
 29 }
 //Makefile的编写
  1 .PHONY:all
  2 all:server client
  3 server:server.c comm.c
  4     gcc -o [email protected] $^
  5 client:client.c comm.c
  6     gcc -o [email protected] $^
  7 .PHONY:clean
  8 clean:
  9     rm -f server client

运行结果:

时间: 2024-10-14 13:09:50

进程间通信:消息队列实现双向通信的相关文章

Linux进程间通信 -- 消息队列 msgget()、msgsend()、msgrcv()、msgctl()

下面来说说如何用不用消息队列来进行进程间的通信,消息队列与命名管道有很多相似之处.有关命名管道的更多内容可以参阅我的另一篇文章:Linux进程间通信 -- 使用命名管道 一.什么是消息队列 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法.  每个数据块都被认为含有一个类型,接收进程可以独立地接收含有不同类型的数据结构.我们可以通过发送消息来避免命名管道的同步和阻塞问题.但是消息队列与命名管道一样,每个数据块都有一个最大长度的限制. Linux用宏MSGMAX和MSGMNB来限制一条

进程间通信——消息队列

1.消息队列的简介 消息队列就是在进程之间架设起通信的通道,信息在通道中传递(具有时间先后的),从宏观逻辑上来讲与管道是一致的.即就是消息队列也同样是:(1).具有入口和出口:(2).消息从入口到出口,是FIFO的:(3).所以消息在其中是队列的存储形式. 消息队列与管道不同的地方在于:管道中的数据并没有分割为一个一个的数据独立单位,在字节流上是连续的.然而,消息队列却将数据分成了一个一个独立的数据单位,每一个数据单位被称为消息体.每一个消息体都是固定大小的存储块儿,在字节流上是不连续的. 2.

进程间通信-----消息队列

消息队列(报文队列):两个进程间通过发送数据块的形式进行通信.一个进程把需要发送的消息通过一个函数发送到消息队列中,另一个进程再从消息队列中读取该消息. 函数: # 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);//创建消息队列,返回消

Linux进程间通信-消息队列

消息队列是在两个进程之间传递二进制块数据的一种简单有效的方式.每个数据块都有一个特定的类型,接收方可以根据类型来有选择的接收数据,而不一定像管道和匿名管道那样必须以先进先出的方式接收数据. Linux消息队列的4个API包括四个系统调用:msgget.msgsnd.msgcrv和msgctl #include <sys/msg.h> int msgget( key_t key, int msgflg ); int msgsnd( int sigid, const void* msg_ptr,

Linux进程间通信—消息队列

四.消息队列(Message Queue) 消息队列就是消息的一个链表,它允许一个或者多个进程向它写消息,一个或多个进程向它读消息.Linux维护了一个消息队列向量表:msgque,来表示系统中所有的消息队列. 消息队列克服了信号传递信息少,管道只能支持无格式字节流和缓冲区受限的缺点. 消息队列用于运行于同一台机器上的进程间通信,它和管道很相似,是一个在系统内核中用来保存消息的队列,它在系统内核中是以消息链表的形式出现.消息链表中节点的结构用msg声明. 事实上,它是一种正逐渐被淘汰的通信方式,

详解linux进程间通信-消息队列

前言:前面讨论了信号.管道的进程间通信方式,接下来将讨论消息队列. 一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构(消息队列.信号量或共享存储段)都用一个非负整数的标识符( i d e n t i f i e r )加以引用. 无论何时创建I P C结构(调用m s g g e t. s e m g e t或s h m g e t) ,都应指定一个关键字(k e y),关键字的数据类型由系统规定为 k e y

Linux 进程间通信 消息队列 实现两个进程间通信

例子: 通过消息队列实现两个进程间通信,一个进程从终端输入数据,通过消息队列发送,另一个进程通过消息队列接收数据 文件1 创建进程1 终端输入通过消息队列发送数据 #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> #include <s

XSI进程间通信-----消息队列

1. 基本特点 1) 消息队列是一个由系统内核负责存储和管理,并通过消息队列标识引用的数据链表,消息队列 和有名管道fifo的区别在: 后者一次只能放一个包,而前者则可以放很多包,这样就能处理发包快,哪包慢的问题 2) 可以通过msgget函数创建一个新的消息队列, 或获取一个已有的消息队列. 通过msgsnd函数 (send)向消息队列的后端追加消息, 通过msgrcv(receive)函数从消息队列的前端提取消息. 3) 消息队列中的每个消息单元除包含消息数据外,还包含消息类型和数据长度.消

Linux --进程间通信--消息队列

一.消息队列的定义 消息队列能够弥补管道的不足,实现双向交互数据,是一个进程向另一进程发送进程块的方法.与管道不同的是,管道是基于字节流的,消息队列是基于消息的,且消息队列的读取不一定是先进先出. 二.消息队列的创建 通过函数int messget(key_t key,int msgflg);创建 key:端口号,可以有 ftok生成. msgflg: IPC_CRTAT 若果 IPC不存在,则创建一个IPC资源, IPC_EXCL:一般和 IPC_CREAT一起使用可以保证所得的对象是新建的,