构造自定义结构化的消息进行文件传输
每个记录前冠以它的长度
PIPE_BUF可原子地写往一个管道或FIFO的最大数据量
把字节流分隔成各个记录由应用程序来实现
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/wait.h>
#define MAXMESGDATA (PIPE_BUF-2*sizeof(long))
#define MESGHDRSIZE (sizeof(struct mymesg)-MAXMESGDATA)
struct mymesg {
long mesg_len;
long mesg_type;
char mesg_data[MAXMESGDATA];
};
ssize_t mesg_send(int fd, struct mymesg *mptr) {
return write(fd, mptr, MESGHDRSIZE+mptr->mesg_len);
}
ssize_t mesg_recv(int fd, struct mymesg *mptr) {
size_t len;
ssize_t n;
if((n=read(fd, mptr, MESGHDRSIZE))==-1) {
fprintf(stderr, "read error.\n");
exit(-1);
} else if(n==0) {
return 0;
} else if(n!=MESGHDRSIZE) {
fprintf(stderr, "message header: expected %d, got %d\n", MESGHDRSIZE, n);
exit(-1);
}
if((len=mptr->mesg_len)>0) {
if((n=read(fd, mptr->mesg_data, len))!=len) {
fprintf(stderr, "message data: expected %d, got %d,\n", len, n);
exit(-1);
}
}
return len;
}
void client(int readfd, int writefd) {
size_t len;
ssize_t n;
struct mymesg mesg;
if(fgets(mesg.mesg_data, MAXMESGDATA, stdin)==NULL) {
fprintf(stderr, "fgets error.\n");
exit(-1);
}
len=strlen(mesg.mesg_data);
if(mesg.mesg_data[len-1]=='\n')
len--;
mesg.mesg_len=len;
mesg.mesg_type=1;
mesg_send(writefd, &mesg);
while((n=mesg_recv(readfd, &mesg))>0) {
write(STDOUT_FILENO, mesg.mesg_data, n);
}
}
void server(int readfd, int writefd) {
FILE *fp;
ssize_t n;
struct mymesg mesg;
mesg.mesg_type=1;
if((n=mesg_recv(readfd, &mesg))==0) {
fprintf(stderr, "pathname missing.\n");
exit(-1);
}
mesg.mesg_data[n]='\0';
if((fp=fopen(mesg.mesg_data, "r"))==NULL) {
snprintf(mesg.mesg_data+n, sizeof(mesg.mesg_data)-n, ": cannot open, %s\n", strerror(errno));
mesg.mesg_len=strlen(mesg.mesg_data);
mesg_send(writefd, &mesg);
} else {
while(fgets(mesg.mesg_data, MAXMESGDATA, fp)!=NULL) {
mesg.mesg_len=strlen(mesg.mesg_data);
mesg_send(writefd, &mesg);
}
fclose(fp);
}
mesg.mesg_len=0;
mesg_send(writefd, &mesg);
}
int main(int argc, char *argv[]) {
int pipe1[2],pipe2[2];
pid_t childpid;
if(pipe(pipe1) < 0) {
perror("pipe1 error.\n");
exit(-1);
}
if(pipe(pipe2) < 0) {
perror("pipe2 error.\n");
exit(-1);
}
if((childpid=fork()) < 0) {
perror("fork error");
exit(-1);
}
else if(childpid == 0) {
if(close(pipe1[1]) == -1) {
perror("close pipe1 error");
exit(-1);
}
if(close(pipe2[0]) == -1) {
perror("close pipe2 error");
exit(-1);
}
server(pipe1[0], pipe2[1]);
exit(0);
}
if(close(pipe1[0]) == -1) {
perror("parent close pipe1 error");
exit(-1);
}
if(close(pipe2[1]) == -1) {
perror("parent close pipe2 error");
exit(-1);
}
client(pipe2[0], pipe1[1]);
if((waitpid(childpid, NULL, 0)) == -1) {
perror("waitpid error");
exit(-1);
}
exit(0);
}
浙公网安备 33010602011771号