IPC-----消息隊列

消息隊列(報文隊列):兩個進程間通過發送數據塊的形式進行通信。一個進程把需要發送的消息通過一個函數發送到消息隊列中,另一個進程再從消息隊列中讀取該消息。

函數:

# 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);//創建消息隊列,返回消息隊列的 msgid

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);//接收消息隊    列中的消息,把接收到的內容寫入msgp中。

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);//將msgp中的內容讀入消息    隊列中。

struct msgstru 

{

  long mtype; //大於0 

  char mtext[用戶指定大小];

};

msgflg:

 1.IPC_CREAT:如果沒有就創建,有就打開。

 2.IPC_EXCL:本身沒多大意義

 3.IPC_CREAT|IPC_EXCL:如果沒有就創建,有就出錯返回,保證每一次創建都是全新的。

特點:

  1. 雙向通信。 

  2. 消息隊列是隨內核持續的。只有在內核重啓或顯示刪除一個消息隊列時,纔會被真正刪除。

  3. 消息隊列是基於消息的。且消息隊列的讀取不一定是先入先出。

  4. 每個消息的最大長度是有上限的(MSGMAX),每個消息隊列的總的字節

  5. 每個消息的最大長度是有上限的(MSGMAX),每個消息隊列的總的字節數是有上限的(MSGMNB),系統上消息隊列的總數也有一個上限(MSGMNI)。

  6. 可避免同步和阻塞問題。

 comm.h
 1 #pragma once
 2 #include<stdio.h>
 3 #include<sys/types.h>
 4 #include<sys/ipc.h>
 5 #include<sys/msg.h>
 6 #include<stdlib.h>
 7 #include<string.h>
 8 
 9 #define _PATH_ "."
 10 #define _PROJ_ID_ 0x7777
 11 #define _MAX_NUM_ 256
 12 #define _SERVER_ 1
 13 #define _CLIENT_ 2
 14 struct msgstru
 15 {
 16     long mtype;
 17     char mtext[_MAX_NUM_];
 18 };
 19 int creat_msg_queue();
 20 int get_msg_queue();
 21 int send_msg(int msgid,char* text,long type);
 22 int recv_msg(int msgid,char* text,long type);
 23 int distroy_msg_queue(int msgid);
 
 comm.c
 1 #include"comm.h"
 2 static int comm_msg_queue(int flag)
 3 {
 4     key_t key = ftok(_PATH_,_PROJ_ID_);
 5     if(key == -1)
 6     {
 7         perror("ftok");
 8         return -1;
 9     }
 10     int msgid = msgget(key,flag);
 11     if(msgid==-1)
 12     {
 13         perror("msgget");
 14         return -1;
 15     }
 16     return msgid;
 17 }
 18 int creat_msg_queue()
 19 {
 20     return comm_msg_queue(IPC_CREAT|IPC_EXCL|0666);
 21 }
 22 int get_msg_queue()
 23 {
 24     return comm_msg_queue(IPC_CREAT);
 25 }
 26 int send_msg(int msgid,char *text,long type)
 27 {
 28     struct msgstru msg;
 29     msg.mtype = type;
 30     strcpy(msg.mtext,text);
 31     if(msgsnd(msgid,&msg,sizeof(msg.mtext),0)==-1)
 32     {
 33         perror("msgsnd");
 34         return -1;
 35     }
 36     return 0;
 37 }
 38 int recv_msg(int msgid,char *text,long type)
 39 {
 40     struct msgstru msg;
 41     memset(msg.mtext,'\0',sizeof(msg.mtext));
 42     if(msgrcv(msgid,&msg,sizeof(msg.mtext),type,0)==-1)
 43     {
 44         perror("msgrcv");
 45         return -1;
 46     }
 47     strcpy(text,msg.mtext);
 48     return 0;
 49 
 50 }
 51 int distroy_msg_queue(int msgid)
 52 {
 53     if(msgctl(msgid,IPC_RMID,NULL)==-1)
 54     {
 55         perror("msgctl");
 56         return -1;
 57     }
 58     return 0;
 59 }
 
 server.c
  1 #include"comm.h"
  2 int main()
  3 {   
  4     int msgid = creat_msg_queue();
  5     if(msgid == -1)
  6     {
  7         return -1;
  8     }
  9     char buf[_MAX_NUM_];
 10     while(1)
 11     {   
 12         memset(buf,'\0',sizeof(buf));
 13         fflush(stdout);
 14         printf("please say#   ");
 15         gets(buf);
 16         if(send_msg(msgid,buf,_SERVER_)==-1)
 17         {
 18             return -1;
 19         }   
 20         if(recv_msg(msgid,buf,_CLIENT_)==-1)
 21         {
 22             return -1;
 23         }
 24         printf("client: %s\n",buf);
 25     }
 26     distroy_msg_queue(msgid);
 27     return 0;
 28 }
 
 client.c
  1 #include"comm.h"
  2 int main()
  3 {   
  4     int msgid = get_msg_queue();
  5     if(msgid==-1)
  6     {   
  7         return -1;
  8     }
  9     char buf[_MAX_NUM_];
 10     while(1)
 11     {   
 12         if(recv_msg(msgid,buf,_SERVER_)<0)
 13         {   
 14             return -1;
 15         }
 16         printf("server: %s\n",buf);
 17         fflush(stdout);
 18         memset(buf,'\0',sizeof(buf));
 19         printf("please say#  ");
 20         gets(buf);
 21         if(send_msg(msgid,buf,_CLIENT_)==-1)
 22         {   
 23             return -1;
 24         }
 25     }
 26     return 0;
 27 }
 
 結果:
 [fbl@localhost msg_queue]$ ./server
please say#   hello
client: hi
please say#   how are you?    
client: fine,and you?
please say#   fine

[fbl@localhost msg_queue]$ ./client
server: hello
please say#  hi
server: how are you?
please say#  fine,and you?
server: fine
please say#


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章