基于消息队列的双向通信

消息队列提供了一种一个进程向另一个进程发送一个数据块的方法。消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的。
消息队列的创建或取得一个已存在的消息队列:
     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 [email protected] $^
   server:server.c comm.c
       gcc -o [email protected] $^
   .PHONY:clean
   clean:
       rm -f client server

上面程序的运行结果:
            

从而实现了简单的收发消息的功能。

				
时间: 2024-08-08 22:07:41

基于消息队列的双向通信的相关文章

几种常见的微服务架构方案简述——ZeroC IceGrid、Spring Cloud、基于消息队列

微服务架构是当前很热门的一个概念,它不是凭空产生的,是技术发展的必然结果.虽然微服务架构没有公认的技术标准和规范草案,但业界已经有一些很有影响力的开源微服务架构平台,架构师可以根据公司的技术实力并结合项目的特点来选择某个合适的微服务架构平台,以此稳妥地实施项目的微服务化改造或开发进程.本文选自<架构解密:从分布式到微服务>一书,了解本书详情请点击阅读原文. 本文盘点了四种常用的微服务架构方案,分别是ZeroC IceGrid.Spring Cloud.基于消息队列与Docker Swarm 1

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

消息队列:操作系统提供缓冲区,提供了一种从一个进程向另一个进程发送一个数据块的方法.消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的. 查看系统消息队列命令:ipcs -q 删除消息队列命令:ipcrm -q 消息id号 相关函数: 原型: 产生消息队列:int msgget(key_t key, int msgflg); 发送消息:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 接收消息:s

消息队列库——ZeroMQ

消息队列库--ZeroMQ ZeroMQ(简称ZMQ)是一个基于消息队列的多线程网络库,其对套接字类型.连接处理.帧.甚至路由的底层细节进行抽象,提供跨越多种传输协议的套接字. ZMQ是网络通信中新的一层,介于应用层和传输层之间(按照TCP/IP划分),其是一个可伸缩层,可并行运行,分散在分布式系统间. ZMQ不是单独的服务,而是一个嵌入式库,它封装了网络通信.消息队列.线程调度等功能,向上层提供简洁的API,应用程序通过加载库文件,调用API函数来实现高性能网络通信. 主线程与I/O线程: I

大型网站架构系列:消息队列

出处:ITFLY8 网址:http://www.cnblogs.com/itfly8/p/5156155.html 一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题.实现高性能,高可用,可伸缩和最终一致性架构.是大型分布式系统不可缺少的中间件. 目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ等. 二.消息队列应用场景 以下介绍消息队列在实际应用中常用的使用场景.异

【系统架构】分布式消息队列

原文地址 以下是消息队列以下的大纲,本文主要介绍消息队列概述,消息队列应用场景和消息中间件示例(电商,日志系统). 本次分享大纲 消息队列概述 消息队列应用场景 消息中间件示例 JMS消息服务(见第二篇:大型网站架构系列:分布式消息队列(二)) 常用消息队列(见第二篇:大型网站架构系列:分布式消息队列(二)) 参考(推荐)资料(见第二篇:大型网站架构系列:分布式消息队列(二)) 本次分享总结(见第二篇:大型网站架构系列:分布式消息队列(二)) 一.消息队列概述 消息队列中间件是分布式系统中重要的

大型网站架构系列:分布式消息队列(一)

以下是消息队列以下的大纲,本文主要介绍消息队列概述,消息队列应用场景和消息中间件示例(电商,日志系统). 本次分享大纲 消息队列概述 消息队列应用场景 消息中间件示例 JMS消息服务 常用消息队列 参考(推荐)资料 本次分享总结 一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题.实现高性能,高可用,可伸缩和最终一致性架构.是大型分布式系统不可缺少的中间件. 目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,K

大型网站架构系列:分布式消息队列(一) (转)

以下是消息队列以下的大纲,本文主要介绍消息队列概述,消息队列应用场景和消息中间件示例(电商,日志系统). 本次分享大纲 消息队列概述 消息队列应用场景 消息中间件示例 JMS消息服务(见第二篇:大型网站架构系列:分布式消息队列(二)) 常用消息队列(见第二篇:大型网站架构系列:分布式消息队列(二)) 参考(推荐)资料(见第二篇:大型网站架构系列:分布式消息队列(二)) 本次分享总结(见第二篇:大型网站架构系列:分布式消息队列(二)) 一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要

大型网站架构之分布式消息队列

以下是消息队列以下的大纲,本文主要介绍消息队列概述,消息队列应用场景和消息中间件示例(电商,日志系统). 本次分享大纲 消息队列概述 消息队列应用场景 消息中间件示例 JMS消息服务 常用消息队列 参考(推荐)资料 本次分享总结 一.消息队列概述 消息队列中间件是分布式系统中重要的组件,主要解决应用耦合,异步消息,流量削锋等问题.实现高性能,高可用,可伸缩和最终一致性架构.是大型分布式系统不可缺少的中间件. 目前在生产环境,使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,K

消息队列设计精要【转】

消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一. 当今市面上有很多主流的消息中间件,如老牌的ActiveMQ.RabbitMQ,炙手可热的Kafka,阿里巴巴自主开发的Notify.MetaQ.RocketMQ等. 本文不会一一介绍这些消息队列的所有特性,而是探讨一下自主开发设计一个消息队列时,你需要思考和设计的重要方面.过程中我们会参考这些成熟消息队列的很多重要思想. 本文首先会阐述什么时候你需要