进程间通信之消息队列

来源:互联网 发布:c 程序员发展方向 编辑:程序博客网 时间:2024/05/22 13:36

这是一个简单的测试

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<string.h>  7 #include<errno.h>  8 #include<stdlib.h>  9  10  11  12 #define CLI_TYPE 1 13 #define SER_TYPE 2 14 #define _PATH_NAME_ "/tmp" 15 #define _PROJ_ID_ 0x6666 16 #define __SIZE__ 1024 17  18 typedef struct msgbuf 19 { 20     long mtype; 21     char mtext[__SIZE__]; 22 }msg_t; 23  24 int create_msg_queue(); 25 int get_msg_queue(); 26 int recv_msg(int msg_id , int type ,char* out); 27 int send_msg(int msg_id ,int types ,const char* msg); 28 int destory_msg(int msg_id);

comm.c

  1 #include"comm.h"  2   3 static int comm_msg(int falg)  4 {  5   6     key_t key = ftok(_PATH_NAME_,_PROJ_ID_);  7     if(key < 0)  8     {  9         perror("ftok"); 10         exit(2); 11     } 12     int msg_id = msgget(key,falg); 13  14     if(msg_id < 0) 15     { 16         perror("msgget"); 17         exit(3); 18     } 19     return msg_id; 20 } 21  22 int create_msg_queue() 23 { 24     int flag = IPC_CREAT|IPC_EXCL|0644; 25     return comm_msg(flag); 26 } 27  28 int get_msg_queue() 29 { 30     int flag =IPC_CREAT ; 31     return comm_msg(flag); 32 } 33  34 int recv_msg(int msg_id , int type ,char* out) 35{  36     msg_t msg ; 37     msg.mtype = type; 38     ssize_t ret = msgrcv(msg_id, &msg ,__SIZE__,type,0); 39     if(ret < 0) 40     { 41         perror("rcv"); 42     } 43     strncpy(out,msg.mtext,sizeof(msg.mtext)); 44     return ret; 45 } 46  47  48  49 int send_msg(int msg_id ,int types ,const char* out) 50 { 51     msg_t msg; 52     msg.mtype = types; 53     strncpy(msg.mtext,out,strlen(out)+1); 54     int _s = msgsnd(msg_id, &msg, sizeof(msg.mtext), 0); 55     if(_s<0) 56     { 57         perror("snd"); 58     } 59     return _s; 60 } 61  62 int destory_msg(int msg_id) 63 { 64     msgctl(msg_id,0,NULL); 65 } 66  67  68  69 

server.c

  1 #include"comm.h"  2   3 int main()  4 {  5     int msg_id = create_msg_queue();  6   7     char buf[__SIZE__];  8     while(1)  9     { 10         memset(buf,0,sizeof(buf)); 11         printf("please enter#"); 12         fflush(stdout); 13  14         ssize_t _r=read(0,buf,sizeof(buf)); 15         if(_r<0) 16         { 17             perror("read"); 18             exit(1); 19         } 20         buf[_r-1] = 0; 21  22         int _s = send_msg(msg_id ,SER_TYPE,buf); 23         if(_s <0 ) 24         { 25             perror("send_msg"); 26             exit(2); 27         } 28  29         if (strcasecmp(buf, "quit") == 0) 30                           break; 31  32         memset(buf,0,sizeof(buf)); 33         int rcv = recv_msg(msg_id ,CLI_TYPE,buf); 34         if (strcasecmp(buf, "quit") == 0) 35                           break; 36         printf("Client#%s\n",buf); 37  38     } 39     destory_msg(msg_id); 40     return 0; 41 }~                                                                                                                                                                                               ~                                                                                                                                                                                               ~                                                                                                                                                                                               ~                                                                                                                                                                                               ~                                                                                                                                                                                               

client.c

  1 #include"comm.h"  2   3 int main()  4 {  5     int msg_id =get_msg_queue();  6   7     char buf[__SIZE__];  8     while(1)  9     { 10         memset(buf,0,sizeof(buf)); 11         int rcv = recv_msg(msg_id ,SER_TYPE,buf); 12  13         if (strcasecmp(buf, "quit") == 0) 14                           break; 15         printf("server#%s\n",buf); 16         fflush(stdout); 17  18         memset(buf,0,sizeof(buf)); 19         printf("please enter#"); 20         fflush(stdout); 21         ssize_t _r=read(0,buf,sizeof(buf)); 22         if(_r<0) 23         { 24             perror("read"); 25             exit(1); 26         } 27         buf[_r-1] = 0; 28  29         int _s = send_msg(msg_id ,CLI_TYPE,buf); 30  31         if (strcasecmp(buf, "quit") == 0) 32                           break; 33         if(_s <0 ) 34         { 35             perror("send_msg"); 36             exit(2); 37         } 38  39     } 40     return 0; 41 }~                                                                                                                                                                                   ~                                                                                                                                                                                   ~                                                                                                                                                                                   ~                                                                                                                                                                                   ~                                                                                                                                                                                   "client.c" 41L, 645C                                                                                                                                              11,1-4        All

总结一下:消息队列的方法是由系统产生一个消息队列(当然得我们自己调用接口 msgget );对于不同的类型,进程可以选择接收(msgrcv)某种特定的类型,或者发送(msgsnd)某种类型到消息队列中;这样的方式就实现了进程的通信。
消息队列 不会随程序的退出而消亡 ; ipcs -q 可以查看;
ipcrm -q key(或者msgid)可以手动删除 亦可以调用 msgctl删除。

0 0
原创粉丝点击