消息队列和共享内存一样,也是一种IPC对象。消息队列其实就是消息的链表,每一则消息都是用户自己的结构体。服务端这边创建消息队列,客户端这边打开消息队列,两个进程就可以进行通信。创建和打开消息队列使用函数msgget,发送消息到消息队列使用函数msgsnd,从消息队列中取出消息使用函数msgrcv,通信完毕后删除消息队列使用函数msgctl。这四个函数就是消息队列通信编程主要用到的函数,man命令就可以看到他们的详细信息。

  前面说到消息是用户自己构造的结构体,其实这个结构体也是有讲究的,这是linux给出的原型

struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[1];    /* message data */
           };

  第一个是整形数字,标识消息的类型,可由用户自己定义。第二个就是消息的内容。其他部分可由用户自己添加。下面直接贴代码吧,感觉代码比文字更直观。我这里只是扫盲式的学了一下,接收消息的时候比较简单粗暴,直接接受了当前队列的第一则消息,没有设置其他的标志。

/*send.c*/
/*send.c*/#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>struct msgt
{
	/*消息类型*/
	int msgtype;
	char student_num[20];
	char name[20];
};int main(int argc, char const *argv[])
{
	int msgid;
	int running = 1;
	int msg_type;
	char number[20];
	char str[20];struct msgt* msgs = (struct msgt*) malloc( sizeof(struct msgt));
 /*构造键值*/
	key_t key = ftok(".", 4); /*创建消息队列*/
	msgid = msgget(key, IPC_CREAT|0666);
	printf("msgid is %d\n", msgid); /*循环*/
	while(running)
	{
		printf("please input message type, 0 for quit\n");
		/*从键盘中读入消息类型和数据*/
		scanf("%d", &msg_type);
		if(msg_type == 0)
		{
			running = 0;
			msgs->msgtype = msg_type;
			msgsnd(msgid, (const void *)msgs, sizeof(struct msgt), 0);
			break;
		}
		printf("please input your student number\n");
		scanf("%s", &number);		printf("please input your name\n");
		scanf("%s", str);
		/*将消息发送到消息队列*/
		msgs->msgtype = msg_type;
		strcpy(msgs->student_num, number);
		strcpy(msgs->name, str);
		msgsnd(msgid, (const void *)msgs, sizeof(struct msgt), 0); }
 /*删除消息队列*/
	msgctl(msgid, IPC_RMID, 0);free((void *) msgs);
 return 0;
}/*recieve.c*/#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>struct msgt
{
	/*消息类型*/
	int msgtype;
	char student_num[20];
	char name[20];
};int main(int argc, char const *argv[])
{

	int i;
	int size;
	int msgid;

	struct msgt* msgs = (struct msgt*) malloc( sizeof(struct msgt)); /*构造键值*/
	key_t key = ftok(".", 4); /*打开消息队列*/
	msgid = msgget(key, IPC_EXCL);printf("msgid is %d\n", msgid);
 while(1)
	{
		size = msgrcv(msgid, msgs, sizeof(struct msgt), 0, 0);
		if(size == -1)
			return;
		printf("your student number is %s\nyour name is %s\nsize is %d\n", msgs->student_num, msgs->name, size);


	}
	free((void *) msgs); return 0;
}


  这里说点写这个程序出现的问题,一开始定义消息结构体的时候我是这么干的

struct msgt* msgs;

  正常运行发送和接收都还好,但是当send输入0退出程序时就出现段错误了,最后用core dump定位才发现定义结构体指针没有初始化,就这破问题调了好久,血淋淋的教训。以后再敲代码的时候一定要记住,结构体指针需要malloc初始化!!!嗯!

  如果有错误或者疑问,欢迎指出!