天天看點

基于消息隊列的雙向通信

       消息隊列提供了一種一個程序向另一個程序發送一個資料塊的方法。消息隊列與管道不同的是,消息隊列是基于消息的,而管道是基于位元組流的。

消息隊列的建立或取得一個已存在的消息隊列:

     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);

          }

          if(msg_queue_recv(msg_id,_SERVER_ID_,buf)<0)

              printf("recv fail\n");

          else

              if(strcmp(buf,"quie")==0)

              {

                printf("server quit\n");

                break;                                                                                                                            

              }

              printf("server: %s\n",buf);

      }

  return 0;

}                                                                                

server.c:檔案:

   #include "comm.h"

       int queue_id=creat_msg_queue();

       if(queue_id<0)

          if(msg_queue_recv(queue_id,_CLIENT_ID_,buf)<0)

              if(strcmp(buf,"quit")==0)

                  printf("client quit\n");

                  break;

              printf("client: %s\n",buf);

          printf("please input: ");

          if(msg_queue_send(queue_id,buf,_SERVER_ID_)<0)

              printf("send fail\n");

      destroy_msg_queue(queue_id);

  }

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檔案:                                                                             

   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 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");

      strcpy(buf,msg.mtext);

  int destroy_msg_queue(int msg_id)

      if(msgctl(msg_id,IPC_RMID,NULL)<0)

         perror("msgct");

         return -1;

      else

          printf("remove success\n");

Makefile檔案的編寫:

   .PHONY:all

   all:client server

   client:client.c comm.c                                                                                                                                  

       gcc -o $@ $^

   server:server.c comm.c

   .PHONY:clean

   clean:

       rm -f client server

上面程式的運作結果:

基于消息隊列的雙向通信
     進而實作了簡單的收發消息的功能。

繼續閱讀