2015-10-03 4 views
1

Я пытаюсь инициировать простой канал в C (используя CygWin и Dev-C++) для передачи значений между родителем и одним дочерним. Вот parent код (pipesnd.c):Не удается правильно прочитать значение из трубы

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
int main() 
{ 
    int FIFO[2]; 
    char *msg = "This is a test message"; 
    char str[10]; 



    if (pipe(FIFO) == -1) 
    { 
     printf("cannot create pipe\n"); 
     exit(1); 
    } 
    write(FIFO[1], msg, strlen(msg)); 

    sprintf(str, "%d", FIFO[0]); 
    printf("I am the parent and this was in the pipe: %s \n", str); 
    fflush(stdout); 




    switch (fork()) 
    { 
    case 0: 
     execl("c:/Dev-Cpp/Lift 2/pipercv", "pipercv", str, NULL); 
     exit(1); 
    case -1: 
     perror("fork() failed:"); 
     exit(2); 
    default: 

    } 






    exit(0); 
} 

И child код (pipercv.c):

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#define NBUF 100 
int main(int argc, char *argv[]) 
{ 
    int fd; 
    char buf[NBUF]; 
    if (argc != 2) 
    { 
     printf("expect pipercv fd\n"); 
     exit(1); 
    } 
    fd = atoi(argv[1]); 


    read(fd, buf, 20); 
    buf[20] = '\0'; 
    printf("I am the child and this was in the pipe: %s \n", buf); 
    fflush(stdout); 
    sleep(10); 

} 

Результат:

enter image description here

Как я могу передать/видеть все сообщение в дочернем и родительском (двунаправленное)?

+0

опубликованный код не компилируется. Он отсутствует. '#include ' 'оператор' switch' имеет несколько проблем в синтаксисе, которые можно исправить, если положить конец 'default:' case с 'break;' – user3629249

+0

: 'printf (" ожидать pipercv fd \ n "); 'действительно должен быть оператором USGE, похожим на:' printf («ИСПОЛЬЗОВАНИЕ:% s fileDescriptor \ n», argv [0]); ' – user3629249

+0

в дочернем, возвращаемое значение из вызова' read() ' должен использоваться как смещение в buf [] для вставки '\ 0'. – user3629249

ответ

0

Проблема в том, что вы читаете 20 символов из buf, затем добавляете \0 в качестве 20-го символа, и вы получаете результат. Ваше сообщение This is a test message содержит больше символов.

+0

Тогда как насчет процесса 'parent'? Почему он показывает только значение '3'? Как я могу попросить «дочерний» процесс показать все сообщение независимо от его длины, будь то 20 символов, 30 или что-то еще? – Bababarghi

+0

См. Этот [пример] (http://web.mst.edu/~ercal/284/PipeExamples/Pipe3.c) –

+0

* Почему оно отображает только значение 3 *, потому что «3» является файловым дескриптором число, а не количество символов, записанных в трубу – user3629249

0

переданная строка на самом деле 24 байта «это тестовое сообщение» + конечный байт NUL.

Считывание только 20 символов является основной частью ошибки.

Предлагайте в ребенке, чтобы инициализировать буфер для всех байт NUL:

char buf[NBUF] = {'\0'}; 

Тогда нет никакой необходимости, чтобы вставить завершающее NUL байт после считывания данных.

Чтобы гарантировать правильное количество байтов, прочитанных в дочернем, предложите второй параметр командной строки для ребенка, который указывает количество прочитанных байтов.

Вместо того, чтобы использовать цикл select/read с таймаутом выбора, используйте счетчик переданных байтов в инструкции read().

+0

Ну, я попытался добавить 'char str [10], Length []; sprintf (Length, "% d", strlen (msg)); 'родительскому коду, а также изменен' execl' на 'execl (« c:/Dev-Cpp/Lift 2/pipercv »,« pipercv », Length, str, NULL); '. Я также обновил дочерний код, чтобы получить дополнительный аргумент для длины переданного сообщения, т. Е. 'Length = atoi (argv [1]); fd = atoi (argv [2]); read (fd, buf, Length); 'Но вывод по-прежнему пуст. Не могли бы вы посоветовать более подробно? – Bababarghi

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