//// first loop it is conduct correctly but, second loop buff or path have strange value
//// please, why can't this code conduct correctly?????
////
#define MAXLINE 4096
#define STDOUT_FILENO 1
void client(int, int), server(int, int);
int main(int argc, char *argv[])
{
char str[MAXLINE];
int maxByte;
int pipe1[2], pipe2[2];
pid_t childpid;
while(1){
pipe(pipe1);
pipe(pipe2);
if((childpid=fork())==0) /* child */ // fork() if child process return 0
{ // else if parent process return child_pid
close(pipe1[0]); // pipe[0] read end of the pipe
close(pipe2[1]); // pipe[1] write end of the pipe
server(pipe2[0], pipe1[1]);
exit(0);
}
/* parent */
close(pipe1[1]);
close(pipe2[0]);
client(pipe1[0], pipe2[1]);
waitpid(childpid, NULL, 0); /* wait for child to terminate */
}
}
void client(int readfd, int writefd)
{
size_t len;
size_t n;
char buff[MAXLINE];
char type[MAXLINE];
char option[MAXLINE];
printf("<client>\n");
/* read pathname */
printf("path: ");
fgets(buff, MAXLINE, stdin);
printf("Read or Write? (r/w)");
fgets(type, MAXLINE, stdin);
printf("Enter correct option(r: byte / w: text)");
fgets(option, MAXLINE, stdin);
strcat(buff, type);
strcat(buff, option);
len = strlen(buff);
if(buff[len-1] == '\n')
len--;
write(writefd, buff, len);
while((n=read(readfd, buff, MAXLINE))>0) {
write(STDOUT_FILENO, buff, n);
}
}
void server(int readfd, int writefd) {
int fd;
int i = 0;
int j = 0;
int tk = 0;
int ok = 0;
int pk = 0;
size_t n;
char buff[MAXLINE+1];
char path[MAXLINE];
char type[MAXLINE];
char option[MAXLINE];
if((n=read(readfd, buff, MAXLINE))==0)
{
printf("end-of-file");
exit(0);
}
buff[n]='\0';
while(buff[j] != '\n') {
path[pk] = buff[j];
j++;
pk++;
}
j++;
while(buff[j] != '\n') {
type[tk] = buff[j];
j++;
tk++;
}
j++;
while(buff[j] != '\0') {
option[ok] = buff[j];
j++;
ok++;
}
printf("Path: %s\n", path);
printf("Type: %s\n", type);
printf("Option: %s\n", option);
if(type[0] == 'r') {
if((fd=open(path,O_RDONLY))<0)
{
snprintf(buff+n, sizeof(buff)-n, ": can't open, %s\n", strerror(errno));
n=strlen(buff);
write(writefd, buff, n);
} else {
while((n=read(fd, buff, MAXLINE))>0) {
write(writefd, buff, atoi(option));
}
close(fd);
}
} else if(type[0] == 'w') {
fd=open(path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
write(fd, option, strlen(option));
close(fd);
}
}
答案 0 :(得分:0)
主要问题是server()
中的代码不会将其复制的字符串终止为path
,type
和option
。
第二个问题是服务器中的代码尝试将选项中的'r'或'w'转换为整数,作为它应该写回的字节数。这转换为0字节。
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "stderr.h"
#define MAXLINE 4096
#define STDOUT_FILENO 1
void client(int, int);
void server(int, int);
int main(int argc, char **argv)
{
int pipe1[2], pipe2[2];
pid_t childpid;
err_setarg0(argv[argc - argc]);
err_setlogopts(ERR_PID|ERR_STAMP);
while (1)
{
if (pipe(pipe1) != 0) err_syserr("failed to create pipe\n");
if (pipe(pipe2) != 0) err_syserr("failed to create pipe\n");
if ((childpid = fork()) == 0) /* child */ // fork() if child process return 0
{
// else if parent process return child_pid
close(pipe1[0]); // pipe[0] read end of the pipe
close(pipe2[1]); // pipe[1] write end of the pipe
server(pipe2[0], pipe1[1]);
exit(0);
}
if (childpid < 0)
err_syserr("failed to fork\n");
/* parent */
close(pipe1[1]);
close(pipe2[0]);
client(pipe1[0], pipe2[1]);
int status;
pid_t corpse = waitpid(childpid, &status, 0); /* wait for child to terminate */
if (corpse != childpid)
err_syserr("Wrong body: expected %d, actual %d\n", childpid, corpse);
err_remark("Child: %d, status 0x%.4X\n", corpse, status);
close(pipe1[0]); // JL
close(pipe2[1]); // JL
}
}
void client(int readfd, int writefd)
{
ssize_t len;
ssize_t n;
char buff[MAXLINE];
char type[MAXLINE];
char option[MAXLINE];
printf("<client>\n");
/* read pathname */
printf("path: ");
if (fgets(buff, MAXLINE, stdin) == 0)
err_syserr("EOF reading path\n");
printf("Read or Write? (r/w)");
if (fgets(type, MAXLINE, stdin) == 0)
err_syserr("EOF reading R/W\n");
printf("Enter correct option(r: byte / w: text)");
if (fgets(option, MAXLINE, stdin) == 0)
err_syserr("EOF reading options\n");
strcat(buff, type);
strcat(buff, option);
len = strlen(buff);
if (buff[len-1] == '\n')
len--;
if (write(writefd, buff, len) != len)
err_syserr("Short write on pipe\n");
err_remark("Wrote message <<%.*s>> to server\n", (int)len, buff);
while ((n = read(readfd, buff, MAXLINE)) > 0)
{
if (write(STDOUT_FILENO, buff, n) != n)
err_syserr("Short write on standard output\n");
}
}
void server(int readfd, int writefd)
{
int fd;
int j = 0;
int tk = 0;
int ok = 0;
int pk = 0;
int n;
char buff[MAXLINE+1];
char path[MAXLINE];
char type[MAXLINE];
char option[MAXLINE];
if ((n = read(readfd, buff, MAXLINE)) == 0)
{
printf("end-of-file\n");
exit(0);
}
err_remark("Got message <<%.*s>> from client\n", (int)n, buff);
buff[n] = '\0';
while (buff[j] != '\n')
{
path[pk] = buff[j];
j++;
pk++;
}
path[pk] = '\0';
j++;
while (buff[j] != '\n')
{
type[tk] = buff[j];
j++;
tk++;
}
type[tk] = '\0';
j++;
while (buff[j] != '\0')
{
option[ok] = buff[j];
j++;
ok++;
}
option[ok] = '\0';
printf("Path: %s\n", path);
printf("Type: %s\n", type);
printf("Option: %s\n", option);
if (type[0] == 'r')
{
if ((fd = open(path, O_RDONLY)) < 0)
{
err_remark("Failed to open file %s\n", path);
snprintf(buff+n, sizeof(buff)-n, ": can't open, %s\n", strerror(errno));
n = strlen(buff);
write(writefd, buff, n);
}
else
{
while ((n = read(fd, buff, MAXLINE)) > 0)
{
if (write(writefd, buff, n) != n)
err_syserr("Short write to client\n");
}
close(fd);
}
}
else if (type[0] == 'w')
{
fd = open(path, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
write(fd, option, strlen(option));
close(fd);
}
}
此代码适用于我。它使用我为错误报告编写的包'stderr。[ch]'。从err_
开始的函数在该包中。
示例输出:
<client>
path: data
Read or Write? (r/w)r
Enter correct option(r: byte / w: text)w
cs: cs: 2013-10-31 21:44:16 - pid=2768: Wrote message <<data
r
w>> to server
2013-10-31 21:44:16 - pid=2769: Got message <<data
r
w>> from client
Path: data
Type: r
Option: w
As a describer of life and manners, he must be allowed to stand perhaps
the first of the first rank. His humour, which, as Steele observes, is
peculiar to himself, is so happily diffused as to give the grace of
novelty to domestic scenes and daily occurrences. He never "o'ersteps
the modesty of nature," nor raises merriment or wonder by the violation
of truth. His figures neither divert by distortion nor amaze by
aggravation. He copies life with so much fidelity that he can be hardly
said to invent; yet his exhibitions have an air so much original, that
it is difficult to suppose them not merely the product of imagination.
cs: 2013-10-31 21:44:16 - pid=2768: Child: 2769, status 0x0000
<client>
path: data
Read or Write? (r/w)r
Enter correct option(r: byte / w: text)w
cs: 2013-10-31 21:44:23 - pid=2768: Wrote message <<data
r
w>> to server
cs: 2013-10-31 21:44:23 - pid=2770: Got message <<data
r
w>> from client
Path: data
Type: r
Option: w
As a describer of life and manners, he must be allowed to stand perhaps
the first of the first rank. His humour, which, as Steele observes, is
peculiar to himself, is so happily diffused as to give the grace of
novelty to domestic scenes and daily occurrences. He never "o'ersteps
the modesty of nature," nor raises merriment or wonder by the violation
of truth. His figures neither divert by distortion nor amaze by
aggravation. He copies life with so much fidelity that he can be hardly
said to invent; yet his exhibitions have an air so much original, that
it is difficult to suppose them not merely the product of imagination.
cs: 2013-10-31 21:44:23 - pid=2768: Child: 2770, status 0x0000
<client>
path: cs: 2013-10-31 21:44:25 - pid=2768: EOF reading path
error (0) Undefined error: 0
end-of-file
正如您所看到的,它能够毫无困难地两次读取同一文件。