客户端向服务器的消息队列发送一个请求消息请求指定名称的文件内容。服务器将文件的内容返回到客户端私有的消息队列中。
mq_recive所指向的接收信息的地址的大小不能小于MSGSIZE。
发送信息时 需要将发送结构体初始化(bzero)
//mq.h
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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;
}