-1
////   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);
    }

}
4

1 回答 1

0

一个主要问题是您的代码 inserver()不会终止它复制到pathtype的字符串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

如您所见,它能够毫无困难地两次读取同一个文件。

于 2013-11-01T04:45:43.730 回答