2013-11-01 88 views
-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); 
    } 

} 

回答

0

一個主要問題是,你在server()代碼不空終止字符串,它複製到pathtypeoption

次要問題是,在服務器代碼試圖到「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 

正如你所看到的,它能夠讀取同一個文件,沒有任何困難。