您好,登录后才能下订单哦!
消息队列:操作系统提供缓冲区,提供了一种从一个进程向另一个进程发送一个数据块的方法。消息队列与管道不同的是,消息队列是基于消息的,而管道是基于字节流的。
查看系统消息队列命令: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进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。