消息队列通信实验报告总结

实验目的

1、了解什么是消息、消息队列
 2、掌握消息传送的机理

msgget

作用:创建消息队列
原型:int msgget(key_t key, int msgflag)
参数:key:键值 IPC_PRIVATE
msgflag:权限
返回值:成功:消息队列ID
出错:-1
头文件: #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
错误:在这里插入图片描述

msgsnd

作用:写数据到消息队列
原型:int msgsnd(int msgid, const void *msggp, size_t msgsize, int msgflg)
参数:msgid消息队列标识符
msggp 消息结构
例如下:
struct msgtype
{
long mtype; /消息类型/
char mtext[256]; /消息正文/
}
msgsize,字节数
msgflg,标识符分类如下
0:当消息队列满时,msgsnd将会阻塞,直到消息能写进消息队列
IPC_NOWAIT:当消息队列已满的时候,msgsnd函数不等待立即返回
IPC_NOERROR:若发送的消息大于size字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。
头文件: #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
错误:在这里插入图片描述

msgrcv

作用:从消息队列中读数据

原型:ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, intmsgflg)

参数:msqid:消息队列标识符

msgp:指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如上方的msggp
msgsz:消息的大小。
msgtyp:消息类型
msgtyp等于0 则返回队列的最早的一个消息
msgtyp大于0,则返回其类型为mtype的第一个消息
msgtyp小于0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息
错误:在这里插入图片描述

msgctl

作用:控制消息队列
原型:int msggctl(intmsgid, int cmd, struct msgid_ds *buf)
参数:msgid 消息队列ID
cmd 命令参数
IPC_STAT 读取消息队列的数据结构, IPC_SET设置消息队列数据结构msgid_ds中的IPC操作权限、 IPC_RMID从系统内核汇总删除消息队列
返回值: 成功 0
出错-1
头文件: #include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

错误:在这里插入图片描述

所作实验代码

要求

将server程序设置为能够并发处理多个客户的程序(参考下图的程序结构),服务器无限循环,CTRL+C结束,设计捕捉信号,信号处理中删除消息队列,服务器收到客户机的消息后发给不同客户机不同的应答消息(内容自定)。
在这里插入图片描述

server

#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdio.h>
#include <unistd.h>
#include<stdlib.h>
#include <string.h>
#include<signal.h>
#define MSGKEY 75

struct msgform
{
	long mtype;
	char mtext[256];
};
int msgid;
void stop(int a){
	printf("server will stop in one second\n");
	sleep(1);
	msgctl(msgid,IPC_RMID,0);
	exit(0);

}
int main()
{
	int pid;
	if( (pid = fork()) == -1){
		perror("fork");
		exit(EXIT_FAILURE);
	}
	else if ( pid == 0)                //子进程
	{
		struct msgform msg1,msg2;
		msgid=msgget(MSGKEY,0777|IPC_CREAT); /*创建消息队列,操作权为可读、写、执行*/
		while(1){
			sleep(2);
		 	msgrcv(msgid,(void *) &msg1,256,1,0); /*接收flag==1消息*/
			printf("server receive client 1:%s",msg1.mtext);	
		 	strcpy(msg2.mtext,"server received!");
		 	msg2.mtype=1;
		 	msgsnd(msgid,&msg2,256,0);   /*发送消息*/
	 		}

	}
	else                             //父进程
	{	
		if((pid=fork())==-1){
			perror("fork");
			exit(0);
		}
		else if(pid==0){//second child
			struct msgform msg1,msg2;
			msgid=msgget(MSGKEY,0777|IPC_CREAT); /*创建消息队列,操作权为可读、写、执行*/
			while(1){
				sleep(2);
					msgrcv(msgid,(void *) &msg1,256,2,0); /*接收flag==2消息*/
					printf("server receive client 2:%s",msg1.mtext);	
					strcpy(msg2.mtext,"server received!");
					msg2.mtype=2;
					msgsnd(msgid,&msg2,256,0);   /*发送消息*/
			}
		
		}
		else{
			printf("press ctrl+c exit!!!\n");
			signal(SIGINT,stop); 
			while(1);
		}
		
	}
}

client

有两个client,代码一致

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#define MSGKEY 75
struct msgform
{
	long mtype;        /*消息类型*/
	char mtext[256];    /*消息正文*/
};
int msgid;
int main()
{ 

	char buffer[256];
	struct msgform msg1,msg2;
	int msgid,pid,*pint;
	msgid=msgget(MSGKEY, 0777); /*打开消息队列*/
	printf("Enter the mssage to send:");
	fgets(msg1.mtext,156,stdin);

	msg1.mtype = 1;
	msgsnd(msgid,&msg1,256,0);  /*发送消息*/
	msgrcv(msgid,&msg2,256,1,0);    /*接收类型为2的消息*/
	printf("receive from server: %s\n",msg2.mtext);
}

运行结果
在这里插入图片描述

发布了2 篇原创文章 · 获赞 8 · 访问量 514

猜你喜欢

转载自blog.csdn.net/qq_41488595/article/details/103054629
今日推荐