基于消息队列的双向通信-创新互联-成都快上网建站

基于消息队列的双向通信-创新互联

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

上面程序的运行结果:
            基于消息队列的双向通信

我们提供的服务有:成都做网站、网站设计、微信公众号开发、网站优化、网站认证、夏津ssl等。为超过千家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的夏津网站制作公司

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



创新互联www.cdcxhl.cn,专业提供香港、美国云服务器,动态BGP最优骨干路由自动选择,持续稳定高效的网络助力业务部署。公司持有工信部办法的idc、isp许可证, 机房独有T级流量清洗系统配攻击溯源,准确进行流量调度,确保服务器高可用性。佳节活动现已开启,新人活动云服务器买多久送多久。


当前名称:基于消息队列的双向通信-创新互联
网站路径:http://kswjz.com/article/disdsh.html
扫二维码与项目经理沟通

我们在微信上24小时期待你的声音

解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流