一、消息队列:从一个进程向另一个进程发送数据块,读取不一定是先入先出。

    管道与消息队列区别:管道基于字节流的,消息队列基于消息;

                        管道只能发送字符串,消息队列有类型;

                        管道随进程,消息队列随内核。

二、创建函数原型:int msgget(key_t key, int msgflg);    //key由ftok生成,IPC_CREAT|IPC_EXCL

    接收消息:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

    发送消息:int msgsnd(int msqid, const void *magp, size_t msgsz, int msgflg) 

    删    除:int msgctl ( int msgqid, int cmd, struct msqid_ds *buf );

    /*  

     *   msqid:消息队列标识码;  msgp:指向缓冲区的指针,暂时存储消息;

     *   msgsz:消息大小;        msgtyp:读取的消息形态,0表示消息队列中的消息都会读取

     *   msgflg:0表示队列满或者空时,采用阻塞等待方式;IPC_NOWAIT表示不做等待,立即返回

     */

      struct msgstru

      {

            long mtype;

            char metext[];

       }


三、代码实现:

//comm.h

#pragma once

#include
#include
#include
#include
#include
#include
#include
#include

#define _SIZE_ 1024
#define _FILEPATH_ ".tmp"
#define _ID_ 0x666

typedef struct _msg_info
{
	long mtype;
	char mtext[_SIZE_];
}msginfo;

int creat_msg();
int get_msg();
int destroy_msg(int);
int rec_msg(int, long);
int send_msg(int, long);

//comm.c

#include"comm.h"

static int com_creat_msg(int flags)
{
	key_t _key = -1;
	_key = ftok(_FILEPATH_, _ID_);
	if(_key == -1)
	{
		perror("ftok");
		return -1;
	}

	int _msg_id = -1;
	_msg_id = msgget(_key, flags);
	if(_msg_id == -1)
	{
		perror("msgget");
		return -1;
	}

	return _msg_id;
}

int creat_msg()
{
	int flags = IPC_CREAT|IPC_EXCL|0666;
	return com_creat_msg(flags);
}

int get_msg()
{
	return com_creat_msg(IPC_CREAT);
}

int rec_msg(int _msg_id, long mtype)
{
	msginfo _info;
	memset(_info.mtext, '\0', sizeof(_info.mtext));
	if(msgrcv(_msg_id, &_info, sizeof(_info.mtext), mtype, 0) < 0)
	{
		perror("msgrcv");
		return -1;
	}
	printf("%s\n",_info.mtext);
	return 0;
}

int send_msg(int _msg_id, long mtype)
{
	msginfo _info;
	memset(_info.mtext, '\0', sizeof(_info.mtext));
	fgets(_info.mtext, _SIZE_, stdin);
	if(strncasecmp(_info.mtext, "quit", 4) == 0)
	{
		return 0;
	}
	_info.mtype = mtype;
	if(msgsnd(_msg_id, &_info, sizeof(_info.mtext), 0) < 0)
	{
		perror("msgsnd");
		return -1;
	}
	return 0;
}
	
int destroy_msg(int _msg_id)
{
	if(msgctl(_msg_id, IPC_RMID, NULL) < 0)
	{
		perror("msgctl");
		return -1;
	}
	return 0;
}

//ser.c

#include"comm.h"

int main()
{
	int _msg_id = get_msg();
	while(1)
	{
		printf("client:>");
		rec_msg(_msg_id, 1);
		fflush(stdout);

		printf("server:>");
		send_msg(_msg_id, 2);
	}
	return 0;
}

//cli.c

#include"comm.h"

int main()
{
	int _msg_id = creat_msg();
	while(1)
	{
		fflush(stdout);
		printf("client:>");
		send_msg(_msg_id, 1);

		printf("server:>");
		rec_msg(_msg_id, 2);
	}
	destroy_msg(_msg_id);
	return 0;
}

四、实现结果:


消息队列(msg)_第1张图片

消息队列(msg)_第2张图片