关于Posix消息队列简单的发送接收消息的练习

根据Unix网络编程卷2进程间通信中的Posix消息通信一章编写一些简单的例子,做此笔记,方便以后查看。

下面这三个程序是相辅相成的,针对同一个消息队列今进行操作。

  1. 创建消息队列程序mqcreatel.c:
    #include <stdio.h>
    #include <mqueue.h>
    #include <unistd.h>
    #include <stdlib.h>//exit
    //一个简单的创建一个消息队列的例子,Posix消息队列至少具有随内核的持续性。
    //注意编译时必须加上-lrt选项方可成功,若要在文件系统中查看创建的消息队列,需要通过man mq_overview命令查看
    #define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)//注意是小括号
    
    struct mq_attr attr;
    
    int main(int argc,char * argv[])
    {
    	int c,flags;
    	mqd_t mqd;
    	flags=O_RDWR|O_CREAT;
    	while((c=getopt(argc,argv,"em:z:"))!=-1)
    	{
    		switch(c)
    		{
    			case 'e'://排它性创建选项
    				flags|=O_EXCL;
    				break;
    			case 'm'://队列中的最大消息数,注意attr.mq_maxmsg 不能超过文件 /proc/sys/fs/mqueue/msg_max 中的数值,我的机器上面是10.
    				attr.mq_maxmsg=atol(optarg);
    				break;
    			case 'z'://队列中的一个消息的最大字节数,attr.mq_msgsize不能超过 /proc/sys/fs/mqueue/msgsize_max 的数值,我的机器上是8192.
    				attr.mq_msgsize=atol(optarg);
    				break;
    		}
    	}
    	if(optind!=argc-1)//getopt在optind中存放下一个待处理参数的下标
    	{
    		printf("usage:mqcreate [-e] [-m maxmsg -z msgsize] <name>\n");
    		exit(1);
    	}
    
    	if((attr.mq_maxmsg!=0&&attr.mq_msgsize==0)||(attr.mq_maxmsg==0&&attr.mq_msgsize!=0))//两个值都必须指定,见man mq_getattr
    	{
    		printf("must specify both -m maxmsg and -z msgsize\n");
    		exit(1);
    	}
    
    	if((mqd=mq_open(argv[optind],flags,FILE_MODE,(attr.mq_maxmsg!=0)? (&attr):NULL))==-1)//注意在linux系统下mq_open函数第一个参数必须以'\'开头且只能包含一个'\'.见man mq_overview
    	{
    	        perror("mq_open wrong!");
    		exit(1);
    	}
    	if((mq_close(mqd))==-1)
    	{
    		perror("mq_close wrong!");
    		exit(1);
    	}
    	exit(0);
    }
    
    编译运行:
  2. 消息发送程序mqsend.c:
    #include <stdio.h>
    #include <stdlib.h>
    #include <mqueue.h>
    #include <unistd.h>//sysconf
    #include <string.h>//strncpy
    //一个简单的Posix消息队列发送消息程序,根据UNP_IPC P65页例子改写。
    #define MAXLINE 1024
    int main(int argc,char * argv[])
    {
    	mqd_t mqd;
    	void *ptr;
    	size_t len;
    	int prio;
    	int c;
    	int maxpro=0;
    	char buf[MAXLINE]={"This is a practice!"};
    	prio=0;
    	if((maxpro=sysconf(_SC_MQ_PRIO_MAX))==-1)//获取系统任意消息的最大优先级
    	{
    		printf("sysconf wrogn!");
    		exit(1);
    	}
    	while((c=getopt(argc,argv,"p:m:"))!=-1)
    	{
    		switch(c)
    		{
    			case 'p':
    				if(maxpro>atol(optarg))
    					prio=atol(optarg);
    				else
    					prio=maxpro;
    				break;
    			case 'm':
    				memset(buf,0,MAXLINE);
    				strncpy(buf,optarg,strlen(optarg));
    				break;
    		}
    	}
    	if(optind!=argc-1)
    	{
    		printf("usage: mqsend [-p priority] [-m message] <name>\n");
    		exit(1);
    	}
    	ptr=(void *)buf;
    	len=strlen(buf);
    	
    	if((mqd=mq_open(argv[optind],O_WRONLY))==-1)
    	{
    		perror("mq_open wrong!");
    		exit(1);
    	}
    	if(mq_send(mqd,ptr,len,prio)==-1)//注意len值应小于此消息队列中规定的每个消息最大字节数,否则报错
    	{
    		perror("mq_send wrong!");
    		exit(1);
    	}
    	exit(0);
    }
    
    编译运行:
  3. 消息接收程序mqreceive.c:
    #include <stdio.h>
    #include <mqueue.h>
    #include <unistd.h>
    #include <stdlib.h>
    //一个简单的从Posix消息队列中读取消息的程序,
    int main(int argc,char *argv[])
    {
    	int c,flags;
    	mqd_t mqd;
    	ssize_t n;
    	int prio;
    	void *buff;
    	struct mq_attr attr;
    	flags=O_RDONLY;
    	while((c=getopt(argc,argv,"n"))!=-1)
    	{
    		switch(c)
    		{
    			case 'n':
    			{
    				flags|=O_NONBLOCK;
    				break;
    			}
    		}
    	}
    	if(optind!=argc-1)
    	{
    		printf("useage: mqreceive [-n] <name>\n");
    		exit(1);
    	}
    	if((mqd=mq_open(argv[optind],flags))==-1)
    	{
    		perror("mq_open wrong!");
    		exit(1);
    	}
    	if(mq_getattr(mqd,&attr)==-1)
    	{
    		perror("mq_getattr wrong!");
    		exit(1);
    	}
    	if((buff=malloc(attr.mq_msgsize))==NULL)
    	{
    		perror("malloc wrong!");
    		exit(1);
    	}
    	if((n=mq_receive(mqd,buff,attr.mq_msgsize,&prio))==-1)//若队列中有消息,返回的是最高优先级的消息。消息自动从队列中删
    	{
    		perror("mq_receive wrong!");
    		exit(1);
    	}
    	printf("read msg priority:%u,len=%d,context:%s\n",prio,n,(char *)buff);
    }
    
    编译运行:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值