linux --消息队列 (文件服务器)





client.c
 
#include "msgque.h"
#include "unpipc.h"
#include <string.h>

#include "myerror.h"

#define path_file "/home/unix/unpv/msg_queue/src/msgque.c"
#define path_file2 "app/main.c"

#define MQ_KEY1 1234L
#define MQ_KEY2 2345L

#define PATH_NAME1 "/root"
#define PRO_ID1   'l'
#define PATH_NAME2 "/etc"
#define PRO_ID2   'k'

void client(int r_id, int w_id);

int main(int argc, char *argv[])
{
    int rkey, wkey;
    int readid, writeid;
    
    wkey = get_key(PATH_NAME1, PRO_ID1);
    rkey = get_key(PATH_NAME2, PRO_ID2);
    
    writeid = get_mqid(wkey, 0);   // 0 is invailed
    readid = get_mqid(rkey, 0);
    
    client(readid, writeid);

    delete_mqid(readid);
    delete_mqid(writeid);

    printf("after exit main..\n");
    pause();
    exit(0);
}

void client(int r_id, int w_id)
{
    size_t len;
    ssize_t n;
    struct my_mesg mesg;

    while (1){

#if 0
        Fgets(mesg.msg_data, MSG_DATA_LEN, stdin);
        len = strlen(mesg.msg_data);

        if (mesg.msg_data[len-1] == '\n')
            len--;
#else
        strcpy(mesg.msg_data, path_file);

        printf("%s\n", mesg.msg_data);
        len = sizeof(path_file);
#endif
        mesg.msg_len = len;
        mesg.msg_type = 1;

        Mesg_send(w_id, &mesg);
        while ( (n = Mesg_recv(r_id, &mesg)) > 0)
            Write(STDOUT_FILENO, mesg.msg_data, n); 

    }   
}

server.c

#include "msgque.h"
#include "unpipc.h"

#include "myerror.h"

/* not use */
#define MQ_KEY1 1234L
#define MQ_KEY2 2345L

#define PATH_NAME1 "/root"
#define PRO_ID1   'l'
#define PATH_NAME2 "/etc"
#define PRO_ID2   'k'

void server(int r_id, int w_id);

int main(int argc, char *argv[])
{
    int rkey, wkey;
    int readid, writeid;
    
    rkey = get_key(PATH_NAME2, PRO_ID1);
    wkey = get_key(PATH_NAME2, PRO_ID2);
    
    readid = get_mqid(rkey, 0); 
    writeid = get_mqid(wkey, 0);   // 0 is invailed
    
    server(readid, writeid);

    exit(0);
}

void server(int r_id, int w_id)
{
    FILE *fp;
    ssize_t n;
    struct my_mesg mesg;

    mesg.msg_type = 1;
    if ( (n = Mesg_recv(r_id, &mesg)) == 0){ 
        err_msg("pathname missing");
        continue;
    }   
    mesg.msg_data[n] = '\0'; // null terminate pathname

    if ( (fp = fopen(mesg.msg_data, "r")) == NULL) 
    {   
        snprintf(mesg.msg_data + n, sizeof(mesg.msg_data) - n, ": can't open, %s\n", strerror(errno));
        mesg.msg_len = strlen(mesg.msg_data);
        Mesg_send(w_id, &mesg);
    }   
    else 
    {   
        while (Fgets(mesg.msg_data, MSG_DATA_LEN, fp) != NULL)
        {   
            mesg.msg_len = strlen(mesg.msg_data);
            Mesg_send(w_id, &mesg);
        }   
        Fclose(fp);
    }   

    mesg.msg_len = 0;
    Mesg_send(w_id, &mesg);
}
msgque.h
#include<stdio.h>
#include<string.h>
#include <errno.h>

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

#define MSG_DATA_LEN    (4096 - 2*sizeof(long))
#define MSG_MAX_LEN     (sizeof(MSG_T) - sizeof(long))


typedef struct my_mesg {
    long        msg_len;
    long        msg_type;
    char        msg_data[MSG_DATA_LEN];
} MSG_T;


int get_key(const char *pathname, int proj_id);
int get_mqid(int key, int oflag);
int delete_mqid(int msqid);
ssize_t mesg_send(int id, struct my_mesg *mptr);
ssize_t mesg_recv(int id, struct my_mesg *mptr);

void Mesg_send(int id, struct my_mesg *mptr);
ssize_t Mesg_recv(int id, struct my_mesg *mptr);
msqgue.c

#include "msgque.h"
#include "myerror.h"

int get_key(const char *pathname, int proj_id)
{
    key_t key = 0;

    /* 创建一个消息队列对象 */
    key = ftok(pathname, proj_id);
    if (key < 0)
    {
        printf ("fail to ftok\n");
        return -1;
    }

    return key;
}

/* not use oflag */
int get_mqid(int key, int oflag)
{
    int mqid;
    //int msg_flags;

#if 1                                 // 此处 如果对象存在就返回该对象,不存在则建立新对象
    mqid = msgget(key, IPC_EXCL);
    if (mqid < 0)
    {
        mqid = msgget(key, IPC_CREAT | 0666);
        if (mqid < 0)
        {
            printf ("fail to msgget\n");
            return -1;
        }
    }
#else
    msg_flags = 0;
    msg_flags |= IPC_CREAT;
    msg_flags |= IPC_EXCL;          // 加上表示如果对象存在就报错,不存在就重新创建
    msg_flags |= 0660;

    //mqid = msgget(key, msg_flags);
    //mqid = msgget(IPC_PRIVATE, msg_flags);
    if (mqid < 0)
    {
        perror ("fail to msgget");
        return -1;
    }

#endif
    return mqid;
}

int delete_mqid(int msqid)
{
    int ret;

    ret = msgctl(msqid, IPC_RMID, NULL);
    if (ret < 0)
    {   
        printf("msgctl: rm msqid failed\n");
        return -1;
    }

    return 0;
}

ssize_t mesg_send(int id, struct my_mesg *mptr)
{

    return (msgsnd(id, &(mptr->msg_type), mptr->msg_len, 0));
}

void Mesg_send(int id, struct my_mesg *mptr)
{
    ssize_t n;

    if ( (n = msgsnd(id, &(mptr->msg_type), mptr->msg_len, 0)) == -1)
        err_sys("mesg_send error");
}

ssize_t mesg_recv(int id, struct my_mesg *mptr)
{
    ssize_t n;

    n = msgrcv(id, &(mptr->msg_type), MSG_DATA_LEN, mptr->msg_type, 0);
    mptr->msg_len = n;

    return n;           /* -1 on error. 0 at EOF, else > 0 */
}

ssize_t Mesg_recv(int id, struct my_mesg *mptr)
{
    ssize_t n;

    if ( (n = mesg_recv(id, mptr)) == -1)
        err_sys("mesg_recv error");

    return (n);
myerror.h

#include    "unpipc.h"

#include    <stdarg.h>      /* ANSI C header file */
#include    <syslog.h>      /* for syslog() */



void err_ret(const char *fmt, ...);
void err_sys(const char *fmt, ...);
void err_dump(const char *fmt, ...);
void err_msg(const char *fmt, ...);
void err_quit(const char *fmt, ...);
myerror.c

#include "myerror.h"

int     daemon_proc;        /* set nonzero by daemon_init() */

static void err_doit(int, int, const char *, va_list);

/* Nonfatal error related to system call
 * Print message and return */

void
err_ret(const char *fmt, ...)
{
    va_list     ap; 

    va_start(ap, fmt);
    err_doit(1, LOG_INFO, fmt, ap);
    va_end(ap);
    return;
}

/* Fatal error related to system call
 * Print message and terminate */

void
err_sys(const char *fmt, ...)
{
    va_list     ap; 

    va_start(ap, fmt);
    err_doit(1, LOG_ERR, fmt, ap);
    va_end(ap);
    exit(1);
}

/* Fatal error related to system call
 * Print message, dump core, and terminate */

void
err_dump(const char *fmt, ...)
{
    va_list     ap; 

    va_start(ap, fmt);
    err_doit(1, LOG_ERR, fmt, ap);
    va_end(ap);
    abort();        /* dump core and terminate */
    exit(1);        /* shouldn't get here */
}

/* Nonfatal error unrelated to system call
 * Print message and return */

void
err_msg(const char *fmt, ...)
{
    va_list     ap; 

    va_start(ap, fmt);
    err_doit(0, LOG_INFO, fmt, ap);
    va_end(ap);
    return;
}

/* Fatal error unrelated to system call
 * Print message and terminate */

void
err_quit(const char *fmt, ...)
{
    va_list     ap;

    va_start(ap, fmt);
    err_doit(0, LOG_ERR, fmt, ap);
    va_end(ap);
    exit(1);
}

/* Print message and return to caller
 * Caller specifies "errnoflag" and "level" */

static void
err_doit(int errnoflag, int level, const char *fmt, va_list ap)
{
    int     errno_save, n;
    char    buf[MAXLINE + 1];

    errno_save = errno;     /* value caller might want printed */
#ifdef  HAVE_VSNPRINTF
    vsnprintf(buf, MAXLINE, fmt, ap);   /* safe */
#else
    vsprintf(buf, fmt, ap);                 /* not safe */
#endif
    n = strlen(buf);
    if (errnoflag)
        snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
    strcat(buf, "\n");

    if (daemon_proc) {
        syslog(level, buf);
    } else {
        fflush(stdout);     /* in case stdout and stderr are the same */
        fputs(buf, stderr);
        fflush(stderr);
    }
    return;
}
Makefile


DIR_INC := -I ./include

DIR_LIB := -Wl,-Bstatic
DIR_LIB += -L ./lib -lunpipc
DIR_LIB += -Wl,-Bdynamic
DIR_LIB += -lrt


OBJS_C := ./src/client.o
OBJS_C += ./src/error.o
OBJS_C += ./src/msgque.o

OBJS_S := ./src/server.o
OBJS_S += ./src/error.o
OBJS_S += ./src/msgque.o

CFLAGS = -Wall -g
TARGET_CLI = cli 
TARGET_SER = ser 

PROGS = client server

all:    ${PROGS}

%.o:%.c
    $(CC) $(CFLAGS) $(DIR_INC) $< -o $@ -c
    
client: $(OBJS_C)
    $(CC) $(CFLAGS) $(OBJS_C) $(DIR_LIB) -o $(TARGET_CLI)

server: $(OBJS_S)
    $(CC) $(CFLAGS) $(OBJS_S) $(DIR_LIB) -o $(TARGET_SER)

clean:
    $(RM) $(OBJS) $(OBJS_C) $(OBJS_S) $(TARGET_CLI) $(TARGET_SER)







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值