一.消息队列
消息队列是一个进程向另一个进程发送一个数据块的方法,所以消息队列是基于消息的,而管道则是基于字节流的。消息队列提供的是进程间的双向通信。
消息队列中的几个原型函数:
1.获取消息信息:int msgget(key_t key,int msgflag);key 是用ftok()函数创建的
2.接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
3.发送消息:int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
4.销毁消息信息:int msfctl(int msgid)
查看key值命令:ipcs -q
删除key值命令:ipcs -q key值
//comm.h #pragma once #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<unistd.h> #include<sys/ipc.h> #include<sys/msg.h> #define _PATH_ "." //路径 #define _PROJ_ID_ 0x7777 #define _BLOCK_SIZE_ 1024 #define _CLIENT_TYPE_ 1 #define _SERVER_TYPE_ 2 struct msgBuf //定义一个消息结构体 { long mtype; //消息类型 char mtext[_BLOCK_SIZE_]; }; static int creat_msg_queue(); int get_msg_queue(); int send_msg_queue(int msg_id,const char*info,long type); int recv_msg_queue(int msg_id,char info[],long type); int destroy_msg_queue(int msg_id); //comm.c #include"comm.h" int get_msg_queue() { return creat_msg_queue(); } static int creat_msg_queue() { key_t key=ftok(_PATH_,_PROJ_ID_); if(key<0) { perror("ftok"); return -1; } int msg_id=msgget(key,IPC_CREAT); if(msg_id<0) { perror("msgget"); return -1; } return msg_id; } int send_msg_queue(int msg_id,const char*info,long type)//将要发送的消息存入mtext中 { struct msgBuf msg; msg.mtype=type; memset(msg.mtext,'\0',sizeof(msg.mtext)); strcpy(msg.mtext,info); if(msgsnd(msg_id,&msg,sizeof(msg.mtext),0)<0) { perror("msgsnd"); return -1; } return 0; } int recv_msg_queue(int msg_id,char* info,long type)//将mtext中的消息拿出放入info中 { struct msgBuf msg; if(msgrcv(msg_id,&msg,sizeof(msg.mtext),type,0)<0) { perror("msgrcv"); return -1; } strcpy(info,msg.mtext); return 0; } int destroy_msg_queue(int msg_id) { if(msgctl(msg_id,IPC_RMID,NULL)<0) { perror("msgctl"); return -1; } return 0; } //server.c 先发送后接收 #include"comm.h" int main() { int msgid=get_msg_queue(); if(msgid<0) { exit(1); } char info[_BLOCK_SIZE_]; while(1) { memset(info,'\0',sizeof(info)); printf("please input:"); fflush(stdout); gets(info); if(send_msg_queue(msgid,info,_SERVER_TYPE_)<0) { printf("send information failed\n"); exit(1); } if(recv_msg_queue(msgid,info,_CLIENT_TYPE_)<0) { printf("recieve information failed\n"); exit(1); } printf("client:%s\n",info); } destroy(msgid); return 0; } //client.c 先接收后发送 #include"comm.h" int main() { int msgid=get_msg_queue(); if(msgid<0) { exit(1); } char info[_BLOCK_SIZE_]; memset(info,'\0',sizeof(info)); printf("when input stop endding...\n"); while(1) { if(recv_msg_queue(msgid,info,_SERVER_TYPE_)<0) { printf("recieve information failed\n"); exit(1); } else { if(strcmp("stop",info)==0) { return 0; } printf("server :%s\n",info); } printf("please input:"); fflush(stdout); gets(info); if(send_msg_queue(msgid,info,_CLIENT_TYPE_)<0) { printf("send information failed\n"); exit(1); } } destroy(msgid); return 0; }
运行结果:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。