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)