消息队列:操作系统提供缓冲区,提供了一种从一个进程向另一个进程发送一个数据块的方法。消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的。
查看系统消息队列命令:ipcs -q
删除消息队列命令:ipcrm -q 消息id号
相关函数:
原型: 产生消息队列:int msgget(key_t key, int msgflg);
发送消息:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
设置消息队列属性原型:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );
参数:系统定义了 3 种 cmd 操作: IPC_STAT , IPC_SET , IPC_RMID
IPC_STAT : 该命令用来获取消息队列对应的 msqid_ds 数据结构,并将其保存到 buf 指定的地址空间。
IPC_SET : 该命令来设置消息队列的属性,要设置的属性存储在buf中。
IPC_RMID : 从内核中删除 msqid 标识的消息队列。
//comm.h 1 #pragma once 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 #include<sys/types.h> 6 #include<unistd.h> 7 #include<sys/ipc.h> 8 #include<sys/msg.h> 9 #define _PATH_ "." 10 #define _PROJ_ID_ 0x777 11 #define _BLOCK_SIZE_ 1024 12 #define _SERVER_MSG_TYPE_ 1 13 #define _CLIENT_MSG_TYPE_ 2 14 struct msgbuf 15 { 16 long mtype; 17 char mtext[_BLOCK_SIZE_]; 18 }; 19 static int comm_msg_queue(int flag); 20 int set_msg_queue(); 21 int get_msg_queue(); 22 int msg_queue_send(int msg_id,const char* msg,long type); 23 int msg_queue_recv(int msg_id,char* msg,long type); 24 int destory_msg_queue(int msgId); //comm.c 1 #include"comm.h" 2 static int comm_msg_queue(int flag) 3 { 4 5 key_t _key=ftok(_PATH_,_PROJ_ID_); 6 if(_key<0) 7 { 8 perror("ftok"); 9 return -1; 10 } 11 int msg_id=msgget(_key,flag); 12 if(msg_id<0) 13 { 14 perror("msgget"); 15 return -1; 16 } 17 return msg_id; 18 } 19 int set_msg_queue() 20 { 21 umask(0); 22 return comm_msg_queue(IPC_CREAT|IPC_EXCL|0666); 23 } 24 int get_msg_queue() 25 { 26 return comm_msg_queue(IPC_CREAT); 27 } 28 int msg_queue_send(int msg_id,const char* message,long type) 29 { 30 struct msgbuf msg; 31 msg.mtype=type; 32 strcpy(msg.mtext,message); 33 if(msgsnd(msg_id,&msg,strlen(msg.mtext),0)<0) 34 { 35 perror("msgsnd"); 36 return -1; 37 } 38 return 0; 39 } 40 int msg_queue_recv(int msg_id,char* msg,long type) 41 { 42 struct msgbuf ret; 43 memset(ret.mtext,'\0',_BLOCK_SIZE_); 44 if(msgrcv(msg_id,&ret,_BLOCK_SIZE_-1,type,0)<0) 45 { 46 perror("msgrcv"); 47 return -1; 48 } 49 strcpy(msg,ret.mtext); 50 return 0; 51 } 52 int destory_msg_queue(int msg_id) 53 { 54 if(msgctl(msg_id,IPC_RMID,NULL)<0) 55 { 56 perror("msgctl"); 57 return -1; 58 } 59 else 60 { 61 printf("remove msg_queue\n"); 62 return 0; 63 } 64 } //server.c 1 #include"comm.h" 2 int main() 3 { 4 int msgid=set_msg_queue(); 5 if(msgid<0) 6 { 7 exit(1); 8 } 9 char buf[_BLOCK_SIZE_]; 10 printf("input quit endding..\n"); 11 while(1) 12 { 13 if(msg_queue_recv(msgid,buf,_CLIENT_MSG_TYPE_)<0) 14 { 15 printf("recv fail\n"); 16 exit(1); 17 } 18 else 19 { 20 if(strcmp("quit",buf)==0) 21 return 0; 22 printf("client:%s\n",buf); 23 } 24 printf("input:"); 25 fflush(stdout); 26 memset(buf,'\0',_BLOCK_SIZE_); 27 gets(buf); 28 if(msg_queue_send(msgid,buf,_SERVER_MSG_TYPE_)<0) 29 { 30 printf("send fail\n"); 31 exit(1); 32 } 33 } 34 destroy(msgid); 35 return 0; 36 } //client.c 1 #include"comm.h" 2 int main() 3 { 4 int msgid=get_msg_queue(); 5 if(msgid<0) 6 { 7 exit(1); 8 } 9 char buf[_BLOCK_SIZE_]; 10 while(1) 11 { 12 fflush(stdout); 13 printf("please input:"); 14 memset(buf,'\0',_BLOCK_SIZE_); 15 gets(buf); 16 if(msg_queue_send(msgid,buf,_CLIENT_MSG_TYPE_)<0) 17 { 18 printf("send fail\n"); 19 exit(1); 20 } 21 if(msg_queue_recv(msgid,buf,_SERVER_MSG_TYPE_)<0) 22 { 23 printf("recv fail\n"); 24 exit(1); 25 } 26 printf("server:%s\n",buf); 27 } 28 return 0; 29 } //Makefile的编写 1 .PHONY:all 2 all:server client 3 server:server.c comm.c 4 gcc -o $@ $^ 5 client:client.c comm.c 6 gcc -o $@ $^ 7 .PHONY:clean 8 clean: 9 rm -f server client
运行结果:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。