Linux(高级编程)7————进程间通信3(消息队列)

1.消息队列什么?
首先我们在学习数据结构后应该对队列有了一个确切的理解,那么在Linux下进程间通信(System V进程间通信)就有这么一种机制。**消息队列概念:**也叫报文队列,其实就是一个消息的链表,发送的数据就是带有类型的数据块。
2.消息队列特性:
1.消息队列是操作系统在内核为我们创建的一个队列。
2.数据传输:用户组织一个带有类型的数据块,添加到队列中,其他进程从队列中读取特定类型的数据。
3.消息队列是全双工(可读可写)。关于全双工对照着半双工去理解即可。
4.消息队列的生命周期随内核。
3.消息队列的操作步骤:
1.创建/打开消息队列。
2.发送数据/接收数据
3.释放消息队列。
4.消息队列各步骤函数原型:

  • 创建/或打开消息队列:
int msgget(key_t key, int msgflg);

参数:
key:内核中消息队列的标识。
msgflg:IPC_CREAT 不存在时创建消息队列,存在时则打开。
IPC_EXCL与IPC_CREAT同用时,若存在则报错。
mode权限。
返回值:成功时返回消息队列句柄;失败时返回-1;
**注意:**key可以通过函数ftok生成
ftok函数原型:

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

ftok通过文件的inode节点号与proj_id计算得到一个key值。不过这样会存在一个缺点:当这个文件被删除或丢失的时候,这个消息队列再通过这样的方式就有可能找不到了。

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

参数:
msqid:操作句柄msgget返回值。
msgp:结构体masgbuf,用户自定义,描述msg类型、以及msg正文。
msgsz:发送数据的大小即就是sizeof(mtext)大小。
msgflg:标志选项。
返回值:成功返回发送的实际字节数,失败返回:-1。

 struct msgbuf {
              long mtype;       /* message type, must be > 0 */			
               char mtext[1];    /* message data */
           };
  • 接收消息:
 ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,
               int msgflg);

参数:
msqid:操作句柄msgget返回值。
msgp:结构体masgbuf,用户自定义,描述msg类型、以及msg正文。
msgsz:期望接收数据的大小。
msgflg:标志选项。0表示如果接收的数据大于msgsz时,接收数据自动截断,否则不截断。
返回值:成功返回发送的实际字节数,失败返回:-1。

  • 消息队列的释放:
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

参数:
msqid:消息队列操作句柄。
cmd:操作选项,常用IPC_RMID,用于删除消息队列。
buf:用于保存消息队列的信息,不需要则可以忽略(NULL)。
返回值:成功0,失败返回-1。
了解这些接口及使用方法就可以直接上代码了
还是server&client通信
server.c:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>

#define KEY 0x123456
#define C 1
#define S 2
//存储消息的结构体
struct msgbuf
{
	long mtype;
	char mtext[1024];
};

int main()
{
	//1.打开/创建消息队列
	int msgid = msgget(KEY,IPC_CREAT|0664);
	struct msgbuf buf;
	while(1)
	{
		printf("please wait the client request...\n");
		//server端接收数据
		msgrcv(msgid,&buf,1024,C,0);
		printf("client say:");
		fflush(stdout);
		printf("%s\n",buf.mtext);	
		printf("server enter#:");
		fflush(stdout);
		scanf("%s",&buf.mtext);
		//server端发送数据
		buf.mtype = S;
		msgsnd(msgid,&buf,strlen(buf.mtext),0);

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

client.c:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>

#define KEY 0x123456
#define C 1
#define S 2
//存储消息的结构体
struct msgbuf
{
	long mtype;
	char mtext[1024];
};

int main()
{
	//1.打开消息队列
	int msgid = msgget(KEY,IPC_CREAT|0664);
	struct msgbuf buf;
	while(1)
	{
		printf("client enter#:");
		fflush(stdout);
		scanf("%s",&buf.mtext);
		//client发送消息
		buf.mtype = C;
		msgsnd(msgid,&buf,strlen(buf.mtext),0);
		printf("please the server respond...\n");
		msgrcv(msgid,&buf,1024,S,0);
		printf("server say:");
		fflush(stdout);
		printf("%s\n",buf.mtext);
	}
	return 0;
}

运行效果展示:
server端:
在这里插入图片描述
client端:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值