15_2 msgsend()和msgrcev()

dm03_msgsend.c

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
 #include <stdlib.h>


//IPC對象;消息隊列是linux內核給你持久化(我們可以從linux內核中獲取消息隊列的信息,修改消息隊列)


//通過msqid刪除消息隊列 ipcrm -q msqid
/*
	
	//可發送的最長消息字節數
	hzmct@U-64:~$ cat /proc/sys/kernel/msgmax 
	8192
	
	//一個特定隊列的最大字節數(這個隊列中所有的消息長度之和)
	hzmct@U-64:~$ cat /proc/sys/kernel/msgmnb 
	16384
	
	//系統中的最大消息數
	hzmct@U-64:~$ cat /proc/sys/kernel/msgmni
	32000

*/
void showq(void * buf)
{
	if(buf == NULL)
	{
		printf("buf == NULL ");
		return;	
	}
	
	struct msqid_ds *msqid_ds = (struct msqid_ds *)buf;
	printf("************************show ipc msgq************************\n");
	printf("該消息隊列對應的鍵:%x\n", msqid_ds->msg_perm.__key);
	printf("該消息隊列訪問權限:%o\n", msqid_ds->msg_perm.mode);
	printf("該消息隊列的序號:%d\n", msqid_ds->msg_perm.__seq);
	
	printf("該消息隊列 UID of owner:%d\n", msqid_ds->msg_perm.uid);
	printf("該消息隊列 GID of owner:%d\n", msqid_ds->msg_perm.gid);
	printf("該消息隊列 UID of creator:%d\n", msqid_ds->msg_perm.cuid);
	printf("該消息隊列 GID of creator:%d\n", msqid_ds->msg_perm.cgid);
	
	
	printf("消息隊列中的消息個數:%d\n", (int)msqid_ds->msg_qnum);
	printf("當前消息隊列中有多少字節:%ld\n", (long int)msqid_ds->__msg_cbytes);
	
	printf("該消息最後發送的時間:%ld, 進程id:%d\n", (long int)msqid_ds->msg_stime, msqid_ds->msg_lspid);
	printf("該消息最後接收的時間:%ld, 進程id:%d\n", (long int)msqid_ds->msg_rtime, msqid_ds->msg_lrpid);
	printf("接收該消息的修改時間:%ld\n", (long int)msqid_ds->msg_ctime);
	printf("消息隊列所有消息之和最大字節數(取決於系統):%d\n", (int)msqid_ds->msg_qbytes);
}


//按照系統規定定義結構體,第一個成員必須是long 
#define BUFSIZE 1024*10 //10k
struct msgbuf {
	long mtype;       // message type, must be > 0
	char mtext[BUFSIZE];    // message data 
};


int main(int argc, char ** argv)
{
	
	int msgid;
	int ret;
	
	if (argc != 3) 
	{
		fprintf(stderr, "Usage:%s <消息類型 type> <消息字節長度 bytes>\n", argv[0]);
		exit(EXIT_FAILURE);	
	}
	
	
	//32與64位系統的 類型長度不一樣
	printf("------sizeof(long):%d\n", (int)sizeof(long));
	printf("------sizeof(int):%d\n", (int)sizeof(int));
	
	msgid = msgget(0x1234, 0666|IPC_CREAT);
	if (msgid == -1) 
	{
		if (errno == ENOENT) 
		{
			printf("自己檢查錯誤, 消息隊列不存在\n");
		}
		
		if (errno == EACCES) 
		{
			printf("自己檢查錯誤, 用戶進程沒有權限訪問\n");
		}
		
		perror("msgget");
		return -1;
	}
	printf("msgid:%d\n", msgid);
	printf("創建消息隊列成功\n");
	
	
	int type = atoi(argv[1]);
	int len = atoi(argv[2]);
	struct msgbuf msgbuf;
	memset(&msgbuf, 0, sizeof(struct msgbuf));
	msgbuf.mtype = type;
	strcpy(msgbuf.mtext,"1234567890abcdefg123456789abcdefg"); 
	//int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
	//若發送數據的長度小於msgbuf.mtext,則進行截斷處理,msgsz不包含消息類型long int的長度
	ret = msgsnd(msgid, &msgbuf, len, IPC_NOWAIT);//消息隊列滿時,非阻塞等待,
	if (ret == -1) 
	{
		perror("msgsnd");
	}

	struct msqid_ds buf;
	memset(&buf, 0, sizeof(struct msqid_ds));
	//獲取隊列狀態
	ret = msgctl(msgid, IPC_STAT, &buf);
	if (ret == -1) 
	{
		perror("獲取消息隊列狀態");
	}
	showq(&buf);
	system("ipcs -q");
	//刪除消息隊列
	/*ret = msgctl(msgid, IPC_RMID, &buf);
	if (ret == -1) 
	{
		perror("刪除消息隊列");
	}
	*/
	return 0;
}


dm04_msgrecv.c

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/ipc.h>

//IPC對象;消息隊列是linux內核給你持久化(我們可以從linux內核中獲取消息隊列的信息,修改消息隊列)

//通過msqid刪除消息隊列 ipcrm -q msqid
/*
	
	//可發送的最長消息字節數
	hzmct@U-64:~$ cat /proc/sys/kernel/msgmax 
	8192
	
	//一個特定隊列的最大字節數(這個隊列中所有的消息長度之和)
	hzmct@U-64:~$ cat /proc/sys/kernel/msgmnb 
	16384
	
	//系統中的最大消息數
	hzmct@U-64:~$ cat /proc/sys/kernel/msgmni
	32000

*/
void showq(void * buf)
{
	if(buf == NULL)
	{
		printf("buf == NULL ");
		return;	
	}
	
	struct msqid_ds *msqid_ds = (struct msqid_ds *)buf;
	printf("************************show ipc msgq************************\n");
	printf("該消息隊列對應的鍵:%x\n", msqid_ds->msg_perm.__key);
	printf("該消息隊列訪問權限:%o\n", msqid_ds->msg_perm.mode);
	printf("該消息隊列的序號:%d\n", msqid_ds->msg_perm.__seq);
	
	printf("該消息隊列 UID of owner:%d\n", msqid_ds->msg_perm.uid);
	printf("該消息隊列 GID of owner:%d\n", msqid_ds->msg_perm.gid);
	printf("該消息隊列 UID of creator:%d\n", msqid_ds->msg_perm.cuid);
	printf("該消息隊列 GID of creator:%d\n", msqid_ds->msg_perm.cgid);
	
	
	printf("消息隊列中的消息個數:%d\n", (int)msqid_ds->msg_qnum);
	printf("當前消息隊列中有多少字節:%ld\n", (long int)msqid_ds->__msg_cbytes);
	
	printf("該消息最後發送的時間:%ld, 進程id:%d\n", (long int)msqid_ds->msg_stime, msqid_ds->msg_lspid);
	printf("該消息最後接收的時間:%ld, 進程id:%d\n", (long int)msqid_ds->msg_rtime, msqid_ds->msg_lrpid);
	printf("接收該消息的修改時間:%ld\n", (long int)msqid_ds->msg_ctime);
	printf("消息隊列所有消息之和最大字節數(取決於系統):%d\n", (int)msqid_ds->msg_qbytes);
}


//按照系統規定定義結構體
#define BUFSIZE 1024*10 //10k

struct msgbuf {
   long mtype;       // message type, must be > 0 類型必須是長整型
   char mtext[BUFSIZE];    // message data 
};


int main(int argc, char ** argv)
{
	
	int msgid;
	int ret;
	int type = 0;//消息類型
	int flag = 0;
	
	if (argc == 1) 
	{
		fprintf(stderr, "Usage:%s <消息類型 type 0 1 2 3> <n 阻塞>\n", argv[0]);
		exit(EXIT_FAILURE);	
	}
	if (argc == 2) 
	{
		type = atoi(argv[1]);//消息類型
	}
	//若輸入3個參數,表示使用非阻塞
	if (argc == 3) 
	{
		type = atoi(argv[1]);		//消息類型
		flag = flag | IPC_NOWAIT;	//設置非阻塞
	}
	
	
	//32與64位系統的 類型長度不一樣
	printf("------sizeof(long):%d\n", (int)sizeof(long));
	printf("------sizeof(int):%d\n", (int)sizeof(int));
	
	//接收程序要指定同一個鍵值
	msgid = msgget(0x1234, 0666|IPC_CREAT);
	if (msgid == -1)
	{
		if (errno == ENOENT) 
		{
			printf("自己檢查錯誤, 消息隊列不存在\n");
		}
		
		if (errno == EACCES) 
		{
			printf("自己檢查錯誤, 用戶進程沒有權限訪問\n");
		}
		
		perror("msgget");
		return -1;
	}
	printf("msgid:%d\n", msgid);
	printf("創建消息隊列成功\n");
	
	
	struct msgbuf msgbuf;
	memset(&msgbuf, 0, sizeof(struct msgbuf));
	ret = msgrcv(msgid, &msgbuf, BUFSIZE, type, flag);
	if (ret == -1) 
	{
		perror("msgsnd");
	}
	msgbuf.mtext[ret] = '\0';
	printf("mtext:%s\n",msgbuf.mtext);

	struct msqid_ds buf;
	memset(&buf, 0, sizeof(struct msqid_ds));
	//獲取隊列狀態
	ret = msgctl(msgid, IPC_STAT, &buf);
	if (ret == -1) 
	{
		perror("獲取消息隊列狀態");
	}
	//showq(&buf);
	system("ipcs -q");
	//刪除消息隊列
	/*ret = msgctl(msgid, IPC_RMID, &buf);
	if (ret == -1) 
	{
		perror("刪除消息隊列");
	}
	*/
	return 0;
}


在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章