- 论坛徽章:
- 0
|
#ifndef __SVMSG_H
#define __SVMSG_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <pthread.h>
#include <sys/msg.h>
#include <sys/types.h>
#include <limits.h>
#include <string.h>
#define SVMSG_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)
#define MQ_KEY1 (1234L)
#define MQ_KEY2 (2345L)
#define MAXMESGDATA (PIPE_BUF - 2*sizeof(long))
struct mymesg {
long mesg_len; /* #bytes in mesg_data, can be 0 */
long mesg_type; /* message type, must be > 0 */
char mesg_data[MAXMESGDATA];
};
ssize_t mesg_send(int id, struct mymesg *mptr);
ssize_t mesg_recv(int id, struct mymesg *mptr);
#endif /* __SVMSG_H */
客户端:
#include "svmsg.h"
void
client(int readid, int writeid)
{
size_t len;
ssize_t n;
char *ptr;
struct mymesg mesg;
/* 4start buffer with msqid and a blank */
snprintf(mesg.mesg_data, MAXMESGDATA, "%d ", readid);
len = strlen(mesg.mesg_data);
ptr = mesg.mesg_data + len;
/* 4read pathname */
fgets(ptr, MAXMESGDATA - len, stdin);
len = strlen(mesg.mesg_data);
if (mesg.mesg_data[len-1] == '\n')
len--; /* delete newline from fgets() */
mesg.mesg_len = len;
mesg.mesg_type = 1;
/* 4write msqid and pathname to server's well-known queue */
mesg_send(writeid, &mesg);
/* 4read from our queue, write to standard output */
while ( (n = mesg_recv(readid, &mesg)) > 0)
write(STDOUT_FILENO, mesg.mesg_data, n);
}
int
main(int argc, char **argv)
{
int readid, writeid;
/* 4server must create its well-known queue */
writeid = msgget(MQ_KEY1, 0);
/* 4we create our own private queue */
readid = msgget(IPC_PRIVATE, SVMSG_MODE | IPC_CREAT);
client(readid, writeid);
/* 4and delete our private queue */
msgctl(readid, IPC_RMID, NULL);
exit(0);
}
服务器:
#include "svmsg.h"
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
void
sig_chld(int signo)
{
pid_t pid;
int stat;
while ( (pid = waitpid(-1, &stat, WNOHANG)) > 0)
;
return;
}
void
server(int readid, int writeid)
{
FILE *fp;
char *ptr;
ssize_t n;
struct mymesg mesg;
void sig_chld(int);
signal(SIGCHLD, sig_chld);
for ( ; ; ) {
/* 4read pathname from our well-known queue */
mesg.mesg_type = 1;
if ( (n = mesg_recv(readid, &mesg)) == 0) {
printf("pathname missing");
continue;
}
mesg.mesg_data[n] = '\0'; /* null terminate pathname */
if ( (ptr = strchr(mesg.mesg_data, ' ')) == NULL) {
printf("bogus request: %s\n", mesg.mesg_data);
continue;
}
*ptr++ = 0; /* null terminate msgid, ptr = pathname */
writeid = atoi(mesg.mesg_data);
if (fork() == 0) { /* child */
if ( (fp = fopen(ptr, "r")) == NULL) {
/* 4error: must tell client */
snprintf(mesg.mesg_data + n, sizeof(mesg.mesg_data) - n,
": can't open, %s\n", strerror(errno));
mesg.mesg_len = strlen(ptr);
memmove(mesg.mesg_data, ptr, mesg.mesg_len);
mesg_send(writeid, &mesg);
} else {
/* 4fopen succeeded: copy file to client's queue */
while (fgets(mesg.mesg_data, MAXMESGDATA, fp) != NULL) {
mesg.mesg_len = strlen(mesg.mesg_data);
mesg_send(writeid, &mesg);
}
fclose(fp);
}
/* 4send a 0-length message to signify the end */
mesg.mesg_len = 0;
mesg_send(writeid, &mesg);
exit(0); /* child terminates */
}
/* parent just loops around */
}
}
int
main(int argc, char **argv)
{
int msqid;
msqid = msgget(MQ_KEY1, SVMSG_MODE | IPC_CREAT);
server(msqid, msqid); /* same queue for both directions */
exit(0);
} |
|