2016-09-23 55 views
1

我是比较新的管道和用C分叉,父母和孩子之间的沟通,虽然stdout和标准输入

我有一个家长和一个子进程,并试图将它们之间的通信。

我创建了一个管道,使得:parent的stdout将连接到child的stdin,并且child的stdout将连接到父级的stdin。

我试图通过它的标准输出发送“A”,然后孩子会从标准输入接收“A”,之后它应该从标准输出发回“父母的标准输入”。

这里是我的代码,

bool pget_input(void){ 
    char buffer[80]; 
    fprintf(stdout,"A"); 
    fprintf(stderr,"Parent sent out 'A' to child \n"); 
    do{ 
     if (!fgets(buffer, 20, stdin)) { 
      fprintf(stderr,"Parent failed to recieve from child\n"); 
      return false;           
     } 
     fprintf(stderr,"Parent receiving from child\n"); 
     if(strcmp(buffer, "B")==0){ 
      fprintf(stderr,"Parent success recieve child's reply"); 
     } 
     continue; 
    }while(true); 
} 
int main(int argc, char** argv){ 

    pid_t pid = fork(); 
    int pipe1[2]; 
    int pipe2[2]; 

    if (pipe(pipe1)==-1 || pipe(pipe2)==-1){ 
     fprintf(stderr,"pipe failed\n"); 
     exit(1); 
    } 

    if(pid > 0){ 
     //parent 
     close(STDIN_FILENO); //close stdin 
     dup(pipe1[0]);   //replace stdin with pipe1 read 
     close(STDOUT_FILENO); //close stdout 
     dup(pipe2[1]);   //replace stdout with pipe2 write 
     //close pipe1 and pipe2 read write 
     close(pipe1[0]);   
     close(pipe1[1]); 
     close(pipe2[0]); 
     close(pipe2[1]); 
     pget_input(); 
     wait(0); 
    }else if(pid ==0){ 
     //child 
     close(STDOUT_FILENO); //close stdout 
     dup(pipe1[1]);   //replace stdout with pipe1 write 
     close(STDIN_FILENO); //close stdin 
     dup(pipe2[0]);   //replace stdin with pipe2 read 

     //close pipe1 and pipe2 read write 
     close(pipe1[0]);   
     close(pipe1[1]); 
     close(pipe2[0]); 
     close(pipe2[1]); 

     execl("./child", "not matter", NULL); 
     perror("execvp failed"); 
      exit(1); 

    }else{ 
     fprintf(stderr,"fork failed\n"); 
     exit(1); 
    } 
    fprintf(stderr,"Exiting\n"); 
    exit(1); 

} 

其中./child:

bool cget_input(void){ 
    char buffer[80], command[80]; 
    fprintf(stderr,"Child trying receive from parent\n"); 
    do{ 
     if (!fgets(buffer, 20, stdin)) { 
      fprintf(stderr,"child failed to receive from parent\n"); 
      return false;           
     } 
     sscanf(buffer, "%s", command); 
     if(strcmp(buffer, "A") == 0){ 
      fprintf(stderr,"Child received 'A' from Parent and sending out 'B'\n"); 
      fprintf(stdout, "B"); 
     } 
     continue; 
    }while(true); 
} 
int main() 
{ 

    if(!cget_input()){ 
     return 0; 
    } 

    return 1; 
} 

至于结果,双方父母和孩子的标准输入没有得到任何东西, 没有去通过

if (!fgets(buffer, 20, stdin)) 

有人能指出我的代码中出了什么问题吗? 谢谢

+0

我不明白你如何用你的管道替换stdin/out。我也没有看到它的原因,因为你总是使用'fprintf'和'fgets',它们不是默认的stdio。为什么不把它传递给你的管道而不是stdio的messiong? –

+0

这是我的任务的一部分。 –

+0

基本上,任务是创建一个可以通过stdin和stdout与HUB进行通信的游戏 –

回答

1

您必须在之前设置管道

这里是秩序的轮廓事情需要做:

  1. 创建管管道()
  2. 家长和孩子各自关闭其管道的两端正确。
  3. 如果需要,父母和孩子可以重定向标准输出,使用dup()和close()关闭()
  4. 此时,您可以在子进程中执行exec()一个新程序,该程序不需要知道已发生的重定向。

分叉后,父母和子女是两个不同的进程,父母没有权力修改那个孩子的文件描述符。任何共享文件描述符必须在fork之前设置。