消息队列是消息的链接表,包括Posix消息队列system V消息队列。消息队列用于运行于同一台机器上的进程间通信,它 和管道很相似,有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了 信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。 我们可以用流管道或者套接口的方式来取代它。
查询系统消息队列:ipcs -q
#include <sys/types.h> #include <sys/ipc.h> #include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf); int msgget(key_t key, int msgflg); int msgrcv(int msqid, void *msg_ptr, size_t msg_sz, long int msgtype, int msgflg); int msgsnd(int msqid, const void *msg_ptr, size_t msg_sz, int msgflg);
- /*msgserver.c*/
-
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <sys/stat.h>
-
- #define MSG_FILE "msgserver.c"
- #define BUFFER 255
- #define PERM S_IRUSR|S_IWUSR
- /* 服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的 */
- /* ipcrm -q <msqid> */
-
- struct msgtype
- {
- long mtype;
- char buffer[BUFFER+1];
- };
-
- int main()
- {
- struct msgtype msg;
- key_t key;
- int msgid;
-
- if((key=ftok(MSG_FILE,'a'))==-1)
- {
- fprintf(stderr,"Creat Key Error:%s\n", strerror(errno));
- exit(1);
- }
-
- if((msgid=msgget(key, PERM|IPC_CREAT|IPC_EXCL))==-1)
- {
- fprintf(stderr, "Creat Message Error:%s\n", strerror(errno));
- exit(1);
- }
- printf("msqid = %d\n", msgid);
- while(1)
- {
- msgrcv(msgid, &msg, sizeof(struct msgtype), 1, 0);
- fprintf(stderr,"Server Receive:%s\n", msg.buffer);
- msg.mtype = 2;
- msgsnd(msgid, &msg, sizeof(struct msgtype), 0);
- }
- exit(0);
- }
- /* msgclient.c */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <sys/types.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <sys/stat.h>
-
- #define MSG_FILE "msgserver.c"
- #define BUFFER 255
- #define PERM S_IRUSR|S_IWUSR
-
- struct msgtype {
- long mtype;
- char buffer[BUFFER+1];
- };
-
- int main(int argc, char **argv)
- {
- struct msgtype msg;
- key_t key;
- int msgid;
-
- if(argc != 2)
- {
- fprintf(stderr,"Usage:%s string\n", argv[0]);
- exit(1);
- }
-
- if((key=ftok(MSG_FILE,'a'))==-1)
- {
- fprintf(stderr,"Creat Key Error:%s\n", strerror(errno));
- exit(1);
- }
-
- if((msgid=msgget(key, PERM))==-1)
- {
- fprintf(stderr,"Creat Message Error:%s\n", strerror(errno));
- exit(1);
- }
-
- msg.mtype = 1;
- strncpy(msg.buffer, argv[1], BUFFER);
- msgsnd(msgid, &msg, sizeof(struct msgtype), 0);
- memset(&msg, '\0', sizeof(struct msgtype));
- msgrcv(msgid, &msg, sizeof(struct msgtype), 2, 0);
- fprintf(stderr, "Client receive:%s\n", msg.buffer);
- exit(0);
- }
|