2016-10-02 50 views
0

我一直堅持讓管道在兩個程序之間工作了幾個小時,而且我卡住了,不確定是否做錯了什麼。我的程序的想法是,我打算使用interface.c打開管道,然後執行db.c。我想用兩個管道在兩個不同的程序之間進行通信。現在,interface.c是'父',db.c是'child',我不確定是否通過execl命令正確地將參數傳遞給管道。一切都編譯正確,但是當我嘗試運行接口程序時,我收到一個錯誤,指出:'錯誤的文件編號'。有沒有可能我沒有正確使用管道?目前,我只是試圖讓我的程序通過管道將一個整數值發送到db.c.任何幫助將非常感激。C中的兩個程序之間的管道

代碼interface.c

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <errno.h> 
#include <sys/wait.h> 
//PIPES: 
// 
//Parent: reads from P1_READ, writes on P1_WRITE 
//Child: reads from P2_READ, writes on P2_WRITE 
#define P1_READ  0 
#define P2_WRITE 1 
#define P2_READ  2 
#define P1_WRITE 3 

// the total number of pipe *pairs* we need 
#define NUM_PIPES 2 

int main(int argc, char *argv[]) 
{ 
    //Create Pipe Array 
    int fd[2*NUM_PIPES]; 

    //For Parameter Passing: 
    char param0[20];  //P1_Read 
    char param1[20];  //P2_Write 
    char param2[20];  //P2_Read 
    char param3[20];  //P1_Write 

    snprintf(param0, sizeof(param0), "%d" , fd[0]); 
    snprintf(param1, sizeof(param1), "%d" , fd[1]); 
    snprintf(param2, sizeof(param2), "%d" , fd[2]); 
    snprintf(param3, sizeof(param3), "%d" , fd[3]); 

    //Variables 
    pid_t pid; 
    int val = 42; 

    //Allocate the PIPES 
    for (int i=0; i<NUM_PIPES; ++i) 
    { 
     if(pipe(fd+(i*2)) < 0) 
     { 
      perror("Failed to allocate the pipes"); 
      exit(EXIT_FAILURE); 
     } 
    } 

    //If the fork of the program does not work: 
    if ((pid = fork()) < 0) 
    { 
     perror("Failed to fork process"); 
     return EXIT_FAILURE; 
    } 



    if(pid == 0) 
    { //Child Process 
     execl("./db", "db", param0, param1, param2, param3, (char *)NULL); 
    } 
    else 
    { //Parent Process 

     //SENDING VALUES HERE 
     close(fd[P2_READ]); 
     close(fd[P2_WRITE]); 
     printf("Interface is sending|%d| to DB\n", val); 
     if(write(fd[P1_WRITE],&val, sizeof(val)) != sizeof(val)) 
     { 
      perror("Interfae failed to send value to DB"); 
      exit(EXIT_FAILURE); 
     } 
    } 

    return 0; 
} 

這是db.c

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <errno.h> 
#include <sys/wait.h> 
#include <sys/types.h> 
//Typedef-Class- 
typedef struct Information 
{ 
    int accountId; 
    int checkNumber; 
    int date; 
    float amount; 
} Information; 

int main(int argc, char *argv[]) 
{ 
//For Input 
    //Account Data 
    Information acctData[25]; 
    int dataStorageLooper = 0;  //How many db entries 

    //For File Input 
    int aVal; 
    int bVal; 
    int cVal; 
    float dVal; 

    //Prepare for file input: 
    FILE * fp; 
    fp = fopen ("accountData.txt", "r"); 

    //Reads Input 
    while(1) 
    { 
     if (fscanf(fp, "%d %d %d %f", &aVal, &bVal, &cVal, &dVal)!=4) 
     { 
      break; 
     } 
     //Puts data into appropriate arrays 
     acctData[dataStorageLooper].accountId= aVal; 
     acctData[dataStorageLooper].checkNumber= bVal; 
     acctData[dataStorageLooper].date= cVal; 
     acctData[dataStorageLooper].amount= dVal; 
     dataStorageLooper++; 
    } 

    //Decrement index to point to last item 
    dataStorageLooper--; 

    //Displays all values 
    printf("\nDisplaying AccountData.txt\n"); 
    for(int i = 0; i < dataStorageLooper; i++) 
    { 
     printf("Line|%d|: Account|%d|: Check|%d|: Date|%d|: Amount|%.2f|\n",i,acctData[i].accountId,acctData[i].checkNumber,acctData[i].date,acctData[i].amount); 
    } 
    //Closes File 
    fclose(fp); 
//End Input 

//Parameter Receiving: 
    int pipes[4];   //Pipe Array 
    int value = 7; 
    int test; 

    //Build the pipes 
    pipes[0] = atoi(argv[1]);  //P1_Read 
    pipes[1] = atoi(argv[2]);  //P2_Write 
    pipes[2] = atoi(argv[3]);  //P2_Read 
    pipes[3] = atoi(argv[4]);  //P1_Write 

    //Troubleshooting  
    printf("The number of parameters: %d\n",argc); 
    printf("Parameter 1: %s\n", argv[0]); 
    printf("I stared correctly\n"); 

    //Testing 
    close(pipes[0]); 
    close(pipes[3]); 

    //SHOULD RECEIVE VALUE HERE 
    test = read(pipes[2], &value, sizeof(value)); 

     if (test < 0) 
     { 
      perror("DB: Failed to read data from parent"); 
      exit(EXIT_FAILURE); 
     } 
     else if (test == 0) 
     { 
      //Unexpected 
      fprintf(stderr, "DB: Read End-Of-File from pipe"); 
     } 
     else 
     { 
      //What did the child receive? 
      printf("DB: Received Value:(%d)\n", value); 
     } 
     close(pipes[2]); 
     close(pipes[1]); 




    return 0; 
} 
+0

我在一兩天前回答了一個關於'interface.c'和'db.c'的問題 - 嗯,是的,它是[使用管道通過C中的argv發送和接收字符數組](http:// stackoverflow.com/questions/39714636/sending-and-receiving-character-array-using-piping-through-argv-in-c/)。不同的用戶,但...。那裏的答案有幫助嗎?它是否讓你有人可以交談? –

回答

0

一個你做錯了,是snprintf荷蘭國際集團的各種要素在fd前值的東西你已經爲它們分配了任何值。這是未定義的行爲,並且您作爲參數傳遞的值完全沒有意義(最好)。

雖然這讓我覺得這是一種非常奇怪的做事方式。通常你只需dup2 fds 0和1,這樣孩子的stdin和stdout就會被重定向到合適的管道fds。

+0

我試圖通過參數來訪問db.c中的管道。我通過他們錯了嗎? – SunBurntIcarus

+0

@sunburst:正如我所說的,當你調用'snprintf(param1,sizeof(param1),「%d」,fd [0]);','fd [0]'還沒有被賦值時,該值是未定義的行爲。 – rici

+0

是的,那是我的問題....儘管謝謝! – SunBurntIcarus