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删除。