Linux系统编程--POSIX消息队列实现文件服务器

客户端向服务器的消息队列发送一个请求消息请求指定名称的文件内容。服务器将文件的内容返回到客户端私有的消息队列中。
mq_recive所指向的接收信息的地址的大小不能小于MSGSIZE。
发送信息时 需要将发送结构体初始化(bzero)

//mq.h
#include<mqueue.h>
#include<stdio.h>
#include<fcntl.h>
#include<stdlib.h>
#include<sys/mman.h>
#include<string.h>
#include<unistd.h>
#include<sys/stat.h>
#include<stdlib.h>
#include<limits.h>
#define MAX 32
#define MSGSIZE 4096
#define MAXMSG 10
#define MAXSIZE MAXMSG-2*sizeof(int)//data最大长度
#define MS_FAIL 0x01
#define MS_BE 0x02
#define MS_ED 0x04
const char *SERVERNAME="/mqserver";//服务器消息队列名称

struct requestMsg{
    char name[MAX];
    char path[MSGSIZE-sizeof(int)-MAX];
    int len;
};
struct responseMsg{
    int type;
    int len;
    char data[MAXSIZE];
};

//mqserver.c
#include"mq.h"
int main(int argc,char *argv[]){
    	mqd_t server_mq;
    	mqd_t client_mq;
    	struct mq_attr attr;
    	ssize_t n;
    	size_t len;
    	int fd;
    	pid_t pid;
    	struct stat st;
    	void *addr;
 	char realPath[MSGSIZE-MAX];
    	struct requestMsg request;
    	struct responseMsg response;
    	bzero((void*)&request,sizeof(request));
    	bzero((void*)&response,sizeof(response));
 	bzero((void*)realPath,MSGSIZE);
    	attr.mq_maxmsg=MAXMSG;
    	attr.mq_msgsize=MSGSIZE;
    	server_mq=mq_open(SERVERNAME,O_CREAT|O_RDONLY,0666,&attr);
   	 while((n=mq_receive(server_mq,(char*)&request,sizeof(request),NULL))>=0){
        pid=fork();
  	if(0==pid) break;
    }
    	client_mq=mq_open(request.name,O_RDWR);
 
 	realpath(request.path,realPath);
  //  write(STDOUT_FILENO,request.path,sizeof(request.path));
   if((fd=open(realPath,O_RDONLY))==-1) 
{
    	response.type=MS_FAIL;
    	mq_send(client_mq,(char*)&response,sizeof(response),0);
    	mq_close(client_mq);
    	exit(1);
}
	fstat(fd,&st);
    	len=st.st_size;
    	addr=mmap(NULL,len,PROT_READ,MAP_SHARED,fd,0);
    	write(STDOUT_FILENO,(char*)addr,len);
   	off_t off=st.st_size-len;
    	response.type=MS_BE;
    	sprintf(response.data,"total %d \n",len);
    	mq_send(client_mq,(char*)&response,sizeof(response),0);
    	bzero(&response.data,sizeof(response.data));
        while(len>MAXSIZE){
        response.type=MS_BE;
        memcpy((void *)response.data,(void *)(addr+off),MAXSIZE);
        response.data[MAXSIZE]='\0';
  response.len=MAXSIZE;
        mq_send(client_mq,(char*)&response,sizeof(response),0);
        len-=MAXSIZE;
        off+=MAXSIZE;
    }
	bzero(&response.data,sizeof(response.data));
        response.type=MS_ED;
        memcpy((void*)response.data,(void *)(addr+off),len);
  response.len=len;
        response.data[len]='\0';
        mq_send(client_mq,(char*)&response,sizeof(response),0);
        exit(1);
    }
//mqclient.c
#include "mq.h"
int main(int argc,char *argv[])
{
    mqd_t mq;
    mqd_t servermq;
    struct requestMsg request;
    struct responseMsg response;
    struct mq_attr attr;
    size_t n;
    void *addr;
    attr.mq_maxmsg=MAXMSG;
    attr.mq_msgsize=MSGSIZE;
  
    mq_unlink(argv[1]);
    mq=mq_open(argv[1],O_RDWR|O_CREAT,0666,&attr);servermq=mq_open(SERVERNAME,O_WRONLY);
    bzero(&request,sizeof(request));
    bzero(&response,sizeof(response));
    memcpy(request.name,argv[1],strlen(argv[1]));
    memcpy(request.path,argv[2],strlen(argv[2]));
    
    request.name[strlen(argv[1])]='\0';
    request.path[strlen(argv[2])]='\0';
    mq_send(servermq,(char*)&request,sizeof(request),0);
    
 	while(1){
    n=mq_receive(mq,(char*)&response,sizeof(response),NULL);
    if(response.type&MS_FAIL) {
    write(STDOUT_FILENO,"not exist\n",10);
    break;
	}
     else if(response.type&MS_BE){
           //1write(STDOUT_FILENO,"begin",6);
            write(STDOUT_FILENO,(char*)response.data,request.len);
        }
        else {
            write(STDOUT_FILENO,(char*)response.data,request.len);
            write(STDOUT_FILENO,"\nover\n",6);
            break;
        }
        }
    mq_close(servermq);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值