感觉Linux消息队列跟什么pipe、socket差不多,都是发信息的。只不过这个是以一截一截的形式来发,而且还可以跟发的这个“截”起一个类型(type)编号。可以取指定类型的最前端的消息。
而消息具体到代码就是一个数据结构
1 struct msgtype { 2 long mtype; 3 char buffer[BUFFER]; 4 };
这个数据结构是自定义的。但是你自己可以更改的地方也就是BUFFER这个值罢了。消息的格式就是一个消息类型(type)和消息内容。
1.
那个ftok函数,按我的理解,他就是要产生一个key值而已,而这个文件地址参数,只是随便拿来用的而已。但是两个进程中用的这个文件地址要对应噢。其实就是想取这个文件的inode中的值而已。其返回值一般是取fname的索引节点号,然后加上id。
2.
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
这个是接受消息的函数,第三个参数size_t msgsz,指的是 “消息内容” 的字长数,而不是整个消息的长度!!!这里特别强调。
下面是一个小例子:一个server, 一个client
1 //server.c 2 3 #include <stdlib.h> 4 #include <stdio.h> 5 #include <string.h> 6 #include <errno.h> 7 #include <sys/types.h> 8 #include <sys/ipc.h> 9 #include <sys/msg.h> 10 #include <sys/stat.h> 11 12 #define MSG_FILE "msgserver.c" 13 #define BUFFER 255 14 #define PERM S_IRUSR|S_IWUSR 15 /* 服务端创建的消息队列最后没有删除,我们要使用ipcrm命令来删除的 */ 16 /* ipcrm -q <msqid> */ 17 18 struct msgtype { 19 long mtype; 20 char buffer[BUFFER+1]; 21 }; 22 23 int main() 24 { 25 struct msgtype msg; 26 key_t key; 27 int msgid; 28 29 if((key=ftok(MSG_FILE,'a'))==-1) 30 { 31 fprintf(stderr,"Creat Key Error:%s\n", strerror(errno)); 32 exit(1); 33 } 34 35 if((msgid=msgget(key, PERM|IPC_CREAT|IPC_EXCL))==-1) 36 { 37 fprintf(stderr, "Creat Message Error:%s\n", strerror(errno)); 38 exit(1); 39 } 40 printf("msqid = %d\n", msgid); 41 while(1) 42 { 43 //取类型为1的消息 44 msgrcv(msgid, &msg, BUFFER + 1, 1, 0); 45 fprintf(stderr,"Server Receive:%s\n", msg.buffer); 46 msg.mtype = 2; 47 strcpy(msg.buffer + strlen(msg.buffer), "\nthis is sent by server.\n\0"); 48 msgsnd(msgid, &msg, BUFFER + 1, 0); 49 } 50 exit(0); 51 }
1 //client 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <errno.h> 6 #include <sys/types.h> 7 #include <sys/ipc.h> 8 #include <sys/msg.h> 9 #include <sys/stat.h> 10 #include <unistd.h> 11 12 #define MSG_FILE "msgserver.c" 13 #define BUFFER 255 14 #define PERM S_IRUSR|S_IWUSR 15 16 struct msgtype { 17 long mtype; 18 char buffer[BUFFER+1]; 19 }; 20 21 int main(int argc, char **argv) 22 { 23 struct msgtype msg; 24 key_t key; 25 int msgid; 26 27 if(argc != 2) 28 { 29 fprintf(stderr,"Usage:%s string/n", argv[0]); 30 exit(1); 31 } 32 33 if((key=ftok(MSG_FILE,'a'))==-1) 34 { 35 fprintf(stderr,"Creat Key Error:%s/n", strerror(errno)); 36 exit(1); 37 } 38 39 if((msgid=msgget(key, PERM))==-1) 40 { 41 fprintf(stderr,"Creat Message Error:%s/n", strerror(errno)); 42 exit(1); 43 } 44 45 msg.mtype = 1; 46 strncpy(msg.buffer, argv[1], BUFFER); 47 msgsnd(msgid, &msg, BUFFER + 1, 0); 48 memset(&msg, '\0', sizeof(struct msgtype)); 49 msgrcv(msgid, &msg, BUFFER + 1, 2, 0); 50 fprintf(stderr, "Client receive:%s\n", msg.buffer); 51 exit(0); 52 }
具体可以看下面几个比较好的链接,我参考的下面的:
http://blog.csdn.net/zhsp1029/article/details/2171462/
http://www.cnblogs.com/codebean/archive/2011/06/16/2082791.html