一、消息队列的定义
消息队列能够弥补管道的不足,实现双向交互数据,是一个进程向另一进程发送进程块的方法。与管道不同的是,管道是基于字节流的,消息队列是基于消息的,且消息队列的读取不一定是先进先出。
二、消息队列的创建
通过函数int messget(key_t key,int msgflg);创建
key:端口号,可以有 ftok生成。
msgflg:
IPC_CRTAT 若果 IPC不存在,则创建一个IPC资源,
IPC_EXCL:一般和 IPC_CREAT一起使用可以保证所得的对象是新建的,而不是打开已有的。
三、向消息队列读数据
msgrcv从队列中取的消息
ssize_t msgrcv(int msqid,void *msgp,size_t msgsz,long msgtyp,int msgflg);
msgsnd将消息放进队列中
int msgsnd(int msqid,const void *msgp,size_t msgsz,int msgflg);
四、设置消息队列属性
int msgctl(int msgqid,int cmd,struct msqid_ds *buf);
*** 可以用man 函数名 查看函数***
程序代码:
coom.h
1 #pragma once
2 #include<stdio.h>
3 #include<stdlib.h>
4 #include<string.h>
5 #include<sys/types.h>
6 #include<sys/ipc.h>
7 #include<sys/msg.h>
8 #define _PATH_ "."
9 #define _PROCID_ 0x776
10 #define _SIZE 1024
11 #define SERVE_MSGTYPE 1
12 #define CLIECT_MSGTYPE 2
13 typedef struct message
14 {
15 long mtype;
16 char mtext[_SIZE];
17 }message;
18 int create_msg(int msg_num);
19 int drstroy_msg(int msg_id);
20 int set_msg();
21 int get_msg();
22 int msg_send(int msg_id,const char* msg,long type);
23 int msg_rec(int msg_id ,char buf[],long type);
comm .c
1 #include"comm.h"
2 int create_msg(int msg_num)
3 {
4 key_t _key=ftok(_PATH_,_PROCID_);
5 if(_key < 0)
6 {
7 perror("ftok");
8 return -1;
9 }
10 int ret= msgget(_key,msg_num);
11 if(ret < 0)
12 {
13 perror("msgget");
14 return -1;
15 }
16 return ret;
17 }
18 int drstroy_msg(int msg_id)
19 {
20 if(msgctl(msg_id,IPC_RMID,NULL) < 0)
21 {
22 perror("msgctl");
23 return -1;
24 }else{
25 printf("remove message_queue\n");
26 return 0;
27 }
28 }
29 int set_msg()
30 {
31 umask(0);
32 return create_msg(IPC_CREAT |IPC_EXCL |0666);
33 }
34 int get_msg()
35 {
36 return create_msg(IPC_CREAT);
37 }
38 int msg_send(int msg_id,const char* msg,long type)
39 {
40 struct message _msg;
41 _msg.mtype=type;
42 strcpy(_msg.mtext,msg);
43 if(msgsnd(msg_id,&_msg,strlen(_msg.mtext),0)< 0)
44 {
45 perror("msg_send error");
46 return -1;
47 }
48 return 0;
49 }
50 int msg_rec(int msg_id,char buf[],long type)
51 {
52 struct message _msg;
53 memset(_msg.mtext,'\0',_SIZE);
54 if(msgrcv(msg_id,&_msg,_SIZE,type,0)< 0)
55 {
56 perror("msg_receve error");
57 return -1;
58 }
59 strcpy(buf,_msg.mtext);
60 return 0;
61 }
62
client.c
1 #include"comm.h"
2 int main()
3 {
4 int msg_id=get_msg();
5 if(msg_id<0)
6 {
7 perror("error");
8 exit(1);
9 }
10 char buf[_SIZE];
11 while(1)
12 {
13 fflush(stdout);
14 printf("please client input: ");
15 memset(buf,'\0',_SIZE);
16 fgets (buf,sizeof(buf),stdin);
17 if(msg_send(msg_id,buf,CLIECT_MSGTYPE)< 0)
18 {
19 perror("send fail");
20 exit(1);
21 }
22
23 if(msg_rec(msg_id,buf,SERVE_MSGTYPE)<0)
24 {
25 perror("recve fail");
26 exit(1);
27 }
28 printf("serve:%s" ,buf);
29 }
30 return 0;
31 }
server.c
1 #include "comm.h"
2 int main()
3 {
4 int msg_id=set_msg();
5 if(msg_id<0)
6 {
7 perror("mig_id");
8 exit(1);
9 }
10 printf("%d\n",msg_id);
11 char buf[_SIZE];
12 while(1)
13 {
14 if(msg_rec(msg_id,buf,CLIECT_MSGTYPE)< 0)
15 {
16 perror("recve fail");
17 exit(1);
18 }
19 else
20 {
21 printf("client :%s",buf);
22 }
23 printf("server please input: ");
24 fflush(stdout);
25 memset(buf,'\0',_SIZE);
26 fgets(buf,_SIZE,stdin);
27 if(msg_send(msg_id,buf,SERVE_MSGTYPE)<0)
28 {
29 perror("send fail");
30 exit(1);
31 }
32 }
33 drstroy_msg(msg_id);
34 return 0;
35 }
运行结果:
转载于:https://blog.51cto.com/9195095/1763148