在C linux中使用管道的2路通信

时间:2014-03-19 11:45:47

标签: c linux pipe communication fgets

我希望父进程和子进程使用管道在C linux中进行通信。首先,我希望父传递一个字符串,然后让孩子确认它。我创建了两个文件描述符。一个用于父母对孩子,即readpipe和其他writepipe for viceversa。问题是它没有把我的数据作为输入。另外,我希望printf语句如“输入你的数据”一次打印,但是因为在fork之后,有两个进程,所以它们被显示两次。任何替代方案??

 //readpipe[0] = child read
 //readpipe[1]= parent write

//writepipe[0]=parent read
//writepipe[1]=child write

 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <string.h>

 int main(void)
 {
      pid_t pid;
      int r;
      /* Hope this is big enough. */
     char buf[1024];
     char cp[50];
     char ans;
     int readpipe[2];
     int writepipe[2];
     int a;
     int b;
     a=pipe(readpipe);
     b=pipe(writepipe);
     if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
     if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }

     printf("\nSEND SOMETHING TO CHILD PROCESS\t");
     scanf(" %c",&ans);
     pid=fork();
     if(pid==-1)
     {
         printf("pid:main");
         exit(1);
     }

     while(ans=='y' || ans=='Y')
     {
        printf("\nEnter data\t"); //printed twice
        fgets(cp, 50, stdin);     //not taking data
        printf("\n%s",cp);        
        if(pid==0)
        { //CHILD PROCESS
         close(readpipe[1]);
         close(writepipe[0]);
         read(readpipe[0],buf,sizeof(buf));
         printf("\nSENT\n %s",buf);
         write(writepipe[1],cp,strlen(cp)+1);
       }
      else
      { //PARENT PROCESS
        close(readpipe[0]);
        close(writepipe[1]);
        write(readpipe[1],cp,strlen(cp)+1);
        read(writepipe[0],buf,sizeof(buf));
        printf("\nRECEIVED\n %s",buf);
     }
     printf("\nSEND SOMETHING TO CHILD PROCESS\t");
     scanf(" %c",&ans);
  }
  close(readpipe[1]);
  close(writepipe[0]);
  close(readpipe[0]);
  close(writepipe[1]);

   return 0;
}

2 个答案:

答案 0 :(得分:1)

你打电话

    printf("\nEnter data\t"); //printed twice
    fgets(cp, 50, stdin);     //not taking data
在之前

,检查您是在父进程还是子进程中。这当然会导致两个进程都打印,并且两者都是标准输入。因此,不清楚哪个进程会读取您输入的日期。

这些问题会出现同样的问题:

 printf("\nSEND SOMETHING TO CHILD PROCESS\t");
 scanf(" %c",&ans);

我建议你重新设计你的程序,以清楚地分离在父进程fork()中运行的代码和在子进程中运行的代码。

答案 1 :(得分:0)

  1. 为什么fgets不接受数据? 在第一次扫描中,您正在读取单个字符,新行仍将在中 输入缓冲区,这将跳过

    要解决这个问题,你应该使用scanf(“%[^ \ n]%* c”,&amp; ans) - 有关详细信息,请参阅this

  2. 找到修改过的代码..它可能会对你有所帮助(从我做出一些改变的时候打破,我验证了基本功能)

  3. int main(void) {

    pid_t pid;
    int r;
    /* Hope this is big enough. */
    char buf[1024];
    char cp[50];
    char ans;
    int readpipe[2];
    int writepipe[2];
    int a;
    int b;
    a=pipe(readpipe);
    b=pipe(writepipe);
    if (a == -1) { perror("pipe"); exit(EXIT_FAILURE); }
    if (b == -1) { perror("pipe"); exit(EXIT_FAILURE); }
    
    printf("\nSEND SOMETHING TO CHILD PROCESS\t");
    scanf("%[^\n]%*c",&ans);
    //ans = getchar();
    fflush(stdin);
    pid=fork();
    if(pid==-1)
    {
        printf("pid:main");
        exit(1);
    }
    
    while(ans=='y' || ans=='Y')
    {
        if(pid==0)
        { 
            //CHILD PROCESS
            close(readpipe[1]);
            close(writepipe[0]);
            if(read(readpipe[0],buf,sizeof(buf)) < 0)
            {
                break;
            }
    
            printf("\nChild Process Read: %s\n",buf);
    
            printf("\n(child)Enter data:\t"); //printed twice
            fgets(cp, 50, stdin);     //not taking data
            printf("\nData Written to Parent%s",cp);
            if(!strncmp("Q",cp,1) || write(writepipe[1],cp,strlen(cp)+1) < 0)
            {
                break;
            }
        }
        else
        { 
            //PARENT PROCESS
            close(readpipe[0]);
            close(writepipe[1]);
            printf("\n(Parent)Enter data\t"); //printed twice
            fgets(cp, 50, stdin);     //not taking data
    
            printf("\nData Writtent to Child: %s",cp);
            if(!strncmp("Q",cp,1) || write(readpipe[1],cp,strlen(cp)+1) < 0)
            {
                break;
            }        
    
            if(read(writepipe[0],buf,sizeof(buf)) < 0)
            {
                break;
            }
            printf("\nParent Process Read: %s\n",buf);
        }
        ans ='y';
    }
    
    close(readpipe[1]);
    close(writepipe[0]);
    close(readpipe[0]);
    close(writepipe[1]);
    return 0;
    

    }