兔子和鹰酱的通话

12 篇文章 0 订阅
10 篇文章 0 订阅

目录

2、消息队列的使用流程

(1)Key值的获取

(2)创建、打开消息队列——msgget

(3)发送消息——msgsnd

(4)接收消息——msgrcv

(5)删除消息队列——msgctl

3、代码实现

4、结果展示


        消息队列就是一些消息的队列,用户可以在消息队列中添加信息和读取消息等。这些消息存在于系统内核中,由“队列ID”来进行标识。消息队列可以实现消息的随时查询。

        消息队列的实现包括创建或者打开消息队列、添加信息、读取信息和控制消息队列这4种操作。

2、消息队列的使用流程

(1)Key值的获取

#include <sys/types.h>
#include <sys/ipc.h>       

key_t ftok(const char *pathname, int proj_id);

参数:
    pathname:任意路径
    proj_id:任意字符

返回值:
            成功返回key值,失败返回-1

(2)创建、打开消息队列——msgget

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);

参数:
    key:通过ftok创建的key值或者使用IPC_PRIVATE创建私有的消息队列
    shmflg:创建共享内存权限,一般填 0664 | IPC_CREAT
    

返回值:
            成功返回消息队列id号,失败返回-1
    
例:
    int msgid = msgget(IPC_PRIVATE, 0664)

(3)发送消息——msgsnd

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

参数:
    msqid:消息队列id
    msgp:跟发送消息相关的结构体的首地址
    msgsz:消息结构体中正文内容的大小
    msgflg:
                0——表示以阻塞方式发送内容
                IPC_NOWAIT——以非阻塞方式发送内容

返回值:

            成功返回0,失败返回-1
    
msgp用法:


#define LEN (sizeof(MSG) - sizeof(long))

typedef struct msgbuf
{
    long mtype;
    char mtext[N];
}MSG;

    MSG msg;
    char buf[N] = {0};
    msg.mtype = 100;
    
    fgets(buf, N, stdin);
    strcpy(msg.mtest, buf)
    
    msgsnd(msgid, &msg, LEN, 0);

(4)接收消息——msgrcv

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

参数:
    msqid:消息队列id
    msgp:接收消息相关的结构体的首地址
    msgsz:消息结构体中正文内容的大小
    msgflg:
                0——表示以阻塞方式接收内容
                IPC_NOWAIT——以非阻塞方式接收内容

(5)删除消息队列——msgctl

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

cmd:操作共享内存的命令
            IPC_STAT:获取共享内存的信息,需要用到第三个参数
            IPC_SET:设置共享内存信息
            IPC_RMID:删除共享内存,第三个参数填空(映射全部取消之后才会删除)

3、代码实现

/*===============================================================
*   Copyright (C) 2022 All rights reserved.
*   
*   文件名称:in.c
*   创 建 者:QiuCC
*   创建日期:2022年08月11日
*   描    述:兔子向鹰酱发送或者接收消息
*
*   更新日志:
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define N 100
#define typeA 100
#define typeB 200
#define LEN (sizeof(MSG) - sizeof(long))

typedef struct msgbuf
{
	long mtype;
	char mtext[64];
}MSG;

int main()
{
	int ret;//返回值
	char buf[N] = {0};//缓冲区
	MSG msg;
	
	//获取Key值
	key_t key = ftok(".", 'a');
	if(key == -1){
		perror("key");
		exit(-1);
	}
	
	//创建消息队列
	int msgid;
	msgid = msgget(key, 0664 | IPC_CREAT);
	if(msgid == -1){
		perror("msget");
		exit(-1);
	}
	
	while(1){
		//发送信息
		memset(&msg, 0, sizeof(MSG));
		memset(buf, 0, N);
		msg.mtype = typeA;//文件类型
		printf("			我:\n			");
		fgets(buf, N, stdin);
		strcpy(msg.mtext, buf);
	
		ret = msgsnd(msgid, &msg, LEN, 0);
		if(-1 == ret){
			perror("msgsnd");
			exit(-1);
		}
	
		//发送退出消息
		if(strcmp(buf, "我先挂了\n") == 0){
			printf("你已经退出聊天\n");
			break;
		}

		//接收信息
		memset(&msg, 0, sizeof(MSG));
		ret = msgrcv(msgid, &msg, LEN, typeB, 0);
		if(ret == -1){
			perror("msgrcv");
			exit(-1);
		}
		strcpy(buf, msg.mtext);
		printf("鹰酱:\n");
		printf("%s", buf);

		//接收到对方退出消息
		if(strcmp(msg.mtext, "我先挂了\n") == 0){
			printf("鹰酱已经挂了\n");
			break;
		}
	}

	//删除消息队列
	ret = msgctl(msgid, IPC_RMID, NULL);

	
	return 0;
}

/*===============================================================
*   Copyright (C) 2022 All rights reserved.
*   
*   文件名称:in.c
*   创 建 者:QiuCC
*   创建日期:2022年08月11日
*   描    述:鹰酱向兔子发送或者接收信息
*
*   更新日志:
*
================================================================*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define N 100
#define typeA 100
#define typeB 200
#define LEN (sizeof(MSG) - sizeof(long))

typedef struct msgbuf
{
	long mtype;
	char mtext[64];
}MSG;


int main()
{
	int ret;//返回值
	char buf[N] = {0};//缓冲区
	MSG msg;
	
	//获取Key值
	key_t key = ftok(".", 'a');
	if(key == -1){
		perror("key");
		exit(-1);
	}
	
	//创建消息队列
	int msgid;
	msgid = msgget(key, 0664 | IPC_CREAT);
	if(msgid == -1){
		perror("msget");
		exit(-1);
	}
	
	while(1){
		//接收信息
		memset(&msg, 0, sizeof(MSG));
		ret = msgrcv(msgid, &msg, LEN, typeA, 0);
		if(ret == -1){
			perror("msgrcv");
			exit(-1);
		}
		strcpy(buf, msg.mtext);
		printf("兔子:\n");
		printf("%s", buf);

		//接收到对方退出消息
		if(strcmp(msg.mtext, "我先挂了\n") == 0){
			printf("兔子已经退出聊天\n");
			break;
		}
	
		//发送信息
		memset(&msg, 0, sizeof(MSG));
		memset(buf, 0, N);
		msg.mtype = typeB;//文件类型
		printf("			我:\n			");
		fgets(buf, N, stdin);
		strcpy(msg.mtext, buf);
	
		ret = msgsnd(msgid, &msg, LEN, 0);
		if(-1 == ret){
			perror("msgsnd");
			exit(-1);
		}
	
		//发送退出消息
		if(strcmp(buf, "我先挂了\n") == 0){
			printf("你已经退出聊天\n");
			break;
		}

	}

	//删除消息队列
	ret = msgctl(msgid, IPC_RMID, NULL);
	
	
	return 0;
}

4、结果展示

从上述结果来看,我们成功的实现了两个进程之间的实时交互!!! 

好的,今天的分享就到这啦!

欢迎大家参考、指正!!!

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玖尾猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值