1. 程式人生 > >system v訊息佇列msgrcv函式

system v訊息佇列msgrcv函式

/*msgrcv函式從訊息佇列接受一個訊息*/
//第一個引數為訊息佇列的標示符msgid
//第二個引數為指標,只想準備傳送的訊息
//第三個為指標,指向訊息長度
//第四個為實現接受優先順序的簡單方式
//第五個為控制著沒有相應型別的訊息可供接受時將要發生的事情
//成功返回實際放到接受緩衝區裡去的字元個數,失敗返回-1
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

#define ERR_EXIT(m)
		do \
		{           \
			perror(m); \
			exit(EXIT_FAILURE); \
		}while(0) 
//第四個引數msgtype,表示接受訊息型別號,無設定時表示按順序接受
//第五個引數msgflg= MSG_NOERROR,訊息大小超過msgsz時被截斷
//訊息結構體,一方面大小需小於系統限制MSGMAX,另外需以long/int長整形開始
/*訊息結構體*/
struct msgbuf{
	long mtype;//佔四個位元組
	char mtext[1];
}

#define MSGMAX 8192
/* ./msg_rcv -n -t 2 *///與getopt有關
//從前向後讀引數存入argv[1],argv[2].....
int main(int argc, char* argv[])
{
	int flag = 0;
	int type = 0;
	int opt;
	while(1){
		opt= getopt(argc, argv, "nt:");
		if(opt == '?')
			exit(EXIT_FAILURE);
		if(opt == -1)
			break;

		switch(opt)
		{
			case 'n':
					/*printf("AAAA\n");*/
					flag |= IPC_NOWAIT;//執行時新增-n引數表示非阻塞接受,出現錯誤時直接報錯終止
					//阻塞接受為程式執行阻塞至此
					break;
			case 't':
					//printf("BBB\n");
					type = atoi(optarg);//-t引數後可新增接受訊息型別好
					//printf("n = %d\n", n);
					break;
		}
	}
	
	int msgid;

	msgid = msgget(1234, 0666 | IPC_CREAT | IPC_EXCL);
	msgid = msgget(1234, 0);//0可以開啟任何許可權的訊息佇列,只打開不建立

	if(msgid == -1)
	{
		ERR_EXIT("msgget");
	}

	printf("msgget success\n");
	
	struct msgbuf *ptr;//訊息結構體
	ptr = (struct msgbuf*)malloc(sizeof(long)+MSGMAX);
	ptr->mtype = type;//mtext未設定,即傳送任意訊息
	int n;
	if((n=msgrcv(msgid, ptr, MSGMAX, type, flag))<0)//當訊息大於限制時,flag阻塞/非阻塞接受
	{
		ERR_EXIT("msgrcv");
	}
	printf("read %d bytes type=%ld\n", n, ptr->mtype);
	return 0;
}