2015-02-23 10 views
0

Привет Я пытаюсь сделать пару труб в c для связи между «сервером» и «интерфейсом». Я получаю странную ошибку, хотя у меня проблемы с отладкой. Я смотрел на это какое-то время, и я боюсь, что я смотрю мимо него в этот момент. Любая помощь будет оценена.Системные вызовы с c

//server file 
// include needed libraries 
#include <errno.h>  // system error numbers 
#include <stdio.h>  // Standard Input and Output Library 
#include <stdlib.h> // Standard General Utilities Library 
#include <string.h> // strings and arrays 
#include <sys/types.h> // needed for pipes to work 
#include <sys/wait.h> // for waitpid 
#include <unistd.h> // sleep 

#define BUFLENMES 65 
#define BUFLEN2 1024 

typedef struct { 
    char id[8]; 
    int odometer; 
    float gallons; 
} gasData; 

// function prototype for comparing ID values 
// using void in order to use built-in sort function 
int compareID(const void *, const void *); 

/**************** Main function *******************/ 
int main (int argc, char *argv[]) { 

    // initialize values for file reading 
    int iter = 0, 
     value = 0,  
     command, 
     outputFD; 

    // set up based on spaces used for delimtation 
    char id[8], 
     odometer[6], 
     gallons[8], 
     err, 
     buffer[BUFLEN2+1]; 

    // get input and output file descriptors for pipes 
    err = sscanf (argv[1], "%d", &command); 
    if (err == 0) { 
     printf("Parameter must be an integer.\n"); 
     exit(2); 
    } 

    err = sscanf (argv[2], "%d", &outputFD); 
    if (err == 0) { 
     printf("Parameter must be an integer.\n"); 
     exit(2); 
    } 

    // initialize struct 
    gasData  gasRecords[20]; 

    // open file that contains the gas data 
    FILE *iFile; 
    iFile = fopen ("./gasData.txt", "r"); 

    //read file for records 
    do { 
     value = fscanf (iFile, "%8s", id); 
     value = fscanf (iFile, "%6s", odometer); 
     value = fscanf (iFile, "%8s", gallons); 

     //store values in gasRecords struct 
     strcpy(gasRecords[iter].id, id); 
     sscanf (odometer, "%d", &gasRecords[iter].odometer); 
     sscanf (gallons, "%f", &gasRecords[iter].gallons); 

     // move to next record 
     iter++; 
    } while (value != EOF); 

    fclose(iFile); 

    // use iter to print records stored into struct 
    printf("\nRecords Stored\n"); 
    for(int i = 0; i < (iter -1) ; i++) { 
     printf("element = %d: ", i); 
     printf("id = %s, ", gasRecords[i].id); 
     printf("odometer = %d, ", gasRecords[i].odometer); 
     printf("gallons = %f\n", gasRecords[i].gallons); 
    } 
    printf("\n"); 

    /***************** act as server ****************/ 
    int odom[iter-1], 
     count; 

    float averageMPG; 
    // checking commands 
    do { 
     char subString[8], 
      finalMessage[BUFLEN2+1], 
      message[BUFLENMES+1], 
      temp[20]; 

     err = read (command, buffer, BUFLEN2); 
      if (err == -1) { 
       printf ("Error on read from pipe [server]: %d\n", errno); 
       exit (3); 
      } 
     buffer[BUFLEN2] = '\0'; 

     if(strstr(buffer, "list,")) { 
      count = 0; 

      // get second part of command after the firs 5 chars 
      for(int i =0; i < 10; i++) { 
       subString[i] = buffer[i + 5]; 
      } 

      // loop through structure for other IDs 
      for(int i =0; i < (iter-1); i++) { 
       if(!strcmp(gasRecords[i].id, subString)) { 
        odom[i] = gasRecords[i].odometer; 
       } 
      } 

      // sort using compareID below and qsort 
      qsort(odom, (iter-1), sizeof(int), compareID); 

      while(count < (iter-1)) { 

       // for each element in odom, check gasRecords 
       for(int i=0; i < (iter-1); i++) { 

        // if both the ID and the odometer match, send back to interface 
        if(!strcmp(gasRecords[i].id, subString) && 
         odom[count] == gasRecords[i].odometer) { 
         char message2[65], 
          temp2[20]; 

         sprintf(temp2, "element %d: ", i); 
         strcpy(message2, temp2); 

         sprintf(temp2, "id = %s, ", gasRecords[i].id); 
         strcat(message2, temp2); 

         sprintf(temp2, "odometer = %d, ", gasRecords[i].odometer); 
         strcat(message2, temp2); 

         sprintf(temp2, "gallons %f\n", gasRecords[i].gallons); 
         strcat(message2, temp2); 
         strcat(finalMessage, message2); 
        } 
       } 
       count++; 
      } 
      strcat(finalMessage, '\0'); 
      err = write (outputFD, finalMessage, strlen(finalMessage)+1); 
      if (err == -1) { 
       printf ("Error on write to interface: %d\n", errno); 
       exit (3); 
      } 
     } 
     else if(strstr(buffer, "mpg,")) { 
      averageMPG = 0.0; 
      count = 0; 

      // get ID into subString 
      for(int i = 0; i < 10; i++) { 
       subString[i] = buffer[i + 4]; 
      } 

      // search for mpg data for id and add it up 
      for(int i = 0; i < (iter-1); i++) { 
       if(!strcmp(gasRecords[i].id, subString)) { 
        averageMPG += gasRecords[i].gallons; 
        count++; 
       } 
      } 

      sprintf(temp, "Average MPG = %f\n", (averageMPG/count)); 
      strcpy(message, temp); 
      message[BUFLENMES] = '\0'; 
      err = write (outputFD, message, strlen(message)+1); 
      if (err == -1) { 
       printf ("Error on write to interface: %d\n", errno); 
       exit (3); 
      } 
     } 

     // if exit is entered print "response: Server complete." 
     else if(!strcmp(buffer, "exit")) { 
      strcpy(message, "Server complete"); 
      message[BUFLENMES] = '\0'; 
      err = write (outputFD, message, strlen(message)+1); 
      if (err == -1) { 
       printf ("Error on write to interface: %d\n", errno); 
       exit (3); 
      } 

     } 

     // check for invalid command 
     else { 
      strcpy(message, "Invalid command"); 
      message[BUFLENMES] = '\0'; 
      err = write (outputFD, message, strlen(message)+1); 
      if (err == -1) { 
       printf ("Error on write to interface: %d\n", errno); 
       exit (3); 
      } 
     } 

    } while(strcmp(buffer, "exit")); 
    return 0; 
} 

/****************** Function *********************/ 
int compareID(const void *first, const void *second) { 
    int f = *((int*)first); 
    int s = *((int*)second); 

    if (f > s) 
     return 1; 
    else if (s > f) 
     return -1; 
    else 
     return 0; 
} 

Вот мой файловый интерфейс

// interface file 

#include <errno.h>  // system error numbers 
#include <stdio.h>  // Standard Input and Output Library 
#include <stdlib.h> // Standard General Utilities Library 
#include <string.h> // strings and arrays 
#include <sys/types.h> // needed for pipes to work 
#include <sys/wait.h> // for waitpid 
#include <unistd.h> // sleep 

// define buffer length 
#define BUFLEN 1024 

int main (int argc, char *argv[]) 
{ 
    int err, 
     i, 
     id, 
     status, 
     pError; 

    char buffer[BUFLEN+1], 
     command[20], 
     tochild[2], 
     toparent[2]; 

    int toChild[2]; // if toChild[1], then writting to child 
    int toParent[2]; // if toParent[1], then writting to parent 

    // turning tochild into a pipe and checking for an error 
    err = pipe(toChild); 
    if (err == -1) { 
     printf ("Error on pipe creation: %d\n", errno); 
     exit (1); 
    } 

    err = pipe(toParent); 
    if (err == -1) { 
     printf ("Error on pipe creation: %d\n", errno); 
     exit (1); 
    } 
    // create child process 
    id = fork(); 

    // if id = 0, in child process 
    if (id == 0) { 

     // set up pipes for passing into server 
     close (toChild[1]); 
     close (toParent[0]); 
     sprintf(tochild, "%d", toChild[0]); 
     sprintf(toparent, "%d", toParent[1]); 
     tochild[1] = '\0'; 
     toparent[1] = '\0'; 

     // exec into server, print records, and wait for instructions 
     err = execl("server", "server", tochild, toparent, 0); 
     if (err == -1) { 
      printf ("Error on execl: %d\n", errno); 
      exit (1); 
     } 
    } 
    // if id > 0, in parent process 
    else if (id > 0) { 

     close (toChild[0]); 
     close (toParent[1]); 
     sleep(1); 

     do { 
      printf("Input command: "); 
      scanf("%s", command); 
      command[19] = '\0'; 
      err = write (toChild[1], command, strlen(command)+1); 
      if (err == -1) { 
       printf ("Error on write to pipe: %d\n", errno); 
       exit (3); 
      } 
      // parent reads back reponse from server read toParent[0] 
      err = read (toParent[0], buffer, BUFLEN); 
      if (err == -1) { 
       printf ("Error on read from pipe: %d\n", errno); 
       exit (3); 
      } 

      buffer[BUFLEN] = '\0'; 
      printf ("Response: %s", buffer); 
      printf("\n"); 

     } while(strcmp(command, "exit") != 0); 
     pError = waitpid(-1, &status, 0); 
     printf("Interface: child process (%d) completed.\n", id); 
     printf("Interface: child process exit status = %d.\n", status); 
     printf("Interface: Complete.\n"); 
     exit (0); 
    } 
    else{ 
     printf("Error creating forked process"); 
     exit (4); 
    } 

} 

// компиляции и ошибки

csci2>g++ -o server Server.c 
csci2>g++ Interface3.c  
csci2>a.out     

Records Stored 
element = 0: id = red, odometer = 90229, gallons = 13.500000 
element = 1: id = red, odometer = 90345, gallons = 14.500000 
element = 2: id = red, odometer = 90453, gallons = 14.200000 
element = 3: id = green, odometer = 23000, gallons = 32.000000 
element = 4: id = green, odometer = 23300, gallons = 31.500000 
element = 5: id = green, odometer = 23546, gallons = 37.799999 
element = 6: id = , odometer = 120000, gallons = 23.700001 
element = 7: id = , odometer = 120200, gallons = 24.670000 
element = 8: id = , odometer = 120423, gallons = 26.799999 
element = 9: id = 9045, odometer = 67321, gallons = 30.100000 
element = 10: id = 9045, odometer = 67412, gallons = 15.900000 
element = 11: id = 9045, odometer = 67689, gallons = 18.900000 

Input command: mpg,red 
Response: Average MPG = 14.066667 

Input command: mgp,green 
Response: Invalid command 
Input command: mpg,green 
Response: Average MPG = 33.766668 

Input command: mpg,9045 
Response: Average MPG = 21.633334 

Input command: list,red 
Response: Average MPG = 21.633334 

Input command: list,red 
Broken pipe 

/* end */ 

его стоит отметить, что средний идентификатор не передается правильно либо. У меня есть .txt файл с этой информацией в нем:

red 90229 13.5 
red 90345 14.5 
red 90453 14.2 
green 23000 32.0 
green 23300 31.5 
green 23546 37.8 
1489 120000 23.7 
1489 120200 24.67 
1489 120423 26.8 
9045 67321 30.1 
9045 67412 15.9 
9045 67689 18.9 
+0

.txt, называется gasData – m34523

ответ

0

Я думаю, что я знаю, что это неправильно, это это

buffer[BUFLEN] = '\0'; 

если полученное для сообщения меньше, чем это, то вы не nul правильно завершения строки, вы должны

buffer[err] = '\0'; 

потому что read() возвращает количество байтов, успешно читать.

И, конечно же, это относится и к этому buffer[BUFLEN2] = '\0';.

+0

Это не взлом совершенно так же, я не получаю: – m34523

+0

ввода команд: список, красный Ответ: Введите команду: – m34523

+0

является то, что один в файле .c? – m34523

Смежные вопросы