2016-12-09 6 views
1

Я пытаюсь отправить массив структур через трубу. У меня есть на структуру:C - Отправка структуры массива по трубе

typedef struct visitordata { 
    char name[80]; 
    char email[80]; 
    int id; 
    char reg_time[9]; 
}visitordata; 

Тогда я

//... 
//ds is the number of struct entries to be stored 
visitordata* V; 
V = (visitordata*)malloc(ds * sizeof(visitordata)); 

pid_t child = fork(); 
if(child < 0) { 
    perror("Fork error"); 
     exit(1); 
    } 
else if (child > 0) { //parent process 
    write(pipefd[1], &V, sizeof(V)); 
    close(pipefd[1]); 
    fflush(NULL); 
    pause(); 

    sleep(1); 
    pause(); 
    kill(child,SIGTERM);     
    waitpid(child, &status, 0); 
} 
else { //child process 
    visitordata* data; 
    close(pipefd[1]); 

    read(pipefd[0], &data, sizeof(data)); 
    close(pipefd[0]); 
    flush(NULL); 
    for (i = 0; i < ds; ++i) { 
     printf("Received: %s\r\n", data[i].name); 
    } 

    kill(getppid(), SIGUSR1); 
    pause();     
} 

Но тогда, если у меня есть две строки для ввода, принимаемый часть печатает только одну строку со строкой «бесплатно» (который я думаю, пришло из имени пользователя на сервере: [email protected]:), а затем Received: без каких-либо других. Что я делаю не так?

EDIT

Обновленный код в соответствии с предложениями:

visitordata* V; 
V = (visitordata*)malloc(ds * sizeof(visitordata)); 

pid_t child = fork(); 
if(child < 0) { 
    perror("Fork error"); 
     exit(1); 
    } 
else if (child > 0) { //parent process 
    write(pipefd[1], V, ds * sizeof(V)); 
    close(pipefd[1]); 
    fflush(NULL); 
    pause(); 

    sleep(1); 
    pause(); 
    kill(child,SIGTERM);     
    waitpid(child, &status, 0); 
} 
else { //child process 
    visitordata* data; 
    data = (visitordata*)malloc(ds * sizeof(visitordata)); 
    close(pipefd[1]); 

    read(pipefd[0], data, ds * sizeof(data)); 
    close(pipefd[0]); 
    flush(NULL); 
    for (i = 0; i < ds; ++i) { 
     printf("Received: %s\r\n", data[i].name); 
    } 

    kill(getppid(), SIGUSR1); 
    pause();     
} 

Теперь мой выход, как это:

Received: 0▒:▒0▒:▒ 
Received: 

EDIT 2

Update d

read(pipefd[0], data, ds * sizeof(data)); 

и

write(pipefd[1], V, ds * sizeof(V)); 

в

read(pipefd[0], data, ds * sizeof(visitordata)); 

и

write(pipefd[1], V, ds * sizeof(visitordata)); 

Теперь мой выход:

Received: 0Tɢ0Tɢ 
Received: 
+0

Вы не должны использовать 'sizeof' в своих' write' и 'read' вызовах. Вы читаете и записываете количество байтов в указателе (например, 4 или 8) - вам нужно передать фактическую длину данных. –

+0

Не могли бы вы объяснить? –

+0

Вскоре добавлю ответ. –

ответ

0

write и read. Вам нужно передать указатель на фактические данные и длину данных в байтах.

Итак:

write(pipefd[1], &V, sizeof(V)); 

должно быть:

write(pipefd[1], V, ds * sizeof(visitordata)); // note: 2 fixes here 

и точно так же:

read(pipefd[0], &data, sizeof(data)); 

должно быть:

read(pipefd[0], data, ds * sizeof(visitordata)); // note: 2 fixes here also 


Кроме того, как указано @Someprogrammerdude, вы не указали указатель data (это всего лишь дикий указатель).Изменение:

visitordata* data; 

к:

visitordata* data = malloc(ds * sizeof(visitordata)); 
+0

Хорошо, теперь я обновил это, но он все еще не работает отлично. Я отредактирую вопрос через минуту. –

+0

О, стреляй, извини, я исправлю это! –

-1

Этот запах:

записи (pipefd [1], & В, SizeOf (V));

Может быть, это лучше:

записи (pipefd [1], V SizeOf (V));

Приемная часть также проблематична. Где выделить для него буфер? visitordata * данные;

1

read() и write() читать и писать до количество запрошенных байтов. Согласно POSIX standard for write():

write() функции будет пытаться записатьnbyte байт из буфер, на который указывает buf в файл, связанный с открытым дескриптора файла, fildes.

...

ВОЗВРАТ СТОИМОСТИ

После успешного завершения, эти функции должны возвращать количество байтов, записанных в файл, связанный с fildes. Это число никогда не должно превышать nbyte. В противном случае -1 должно быть возвращено и errno установлено, чтобы указать ошибку.

Ваш код не проверяет результаты записи - вы просто надежду это работает. Для обеспечения всего запрошенного количества байт написано, что вам нужно что-то вроде этого:

size_t bytesToWrite = ds * sizeof(visitordata); 
size_t totalWritten = 0; 

for (;;) 
{ 
    ssize_t bytesWritten = write(pipefd[1], V + totalWritten, 
     bytesToWrite - totalWritten); 
    if (bytesWritten <= 0) 
    { 
     break; 
    } 

    totalWritten += bytesWritten; 
} 

Вам нужно обрабатывать read() аналогичным образом.

+0

Мой выход по-прежнему сохраняется в памяти:/ –

+0

@lte__ Вы сделали то же самое на стороне 'read()'?Вы используете отладчик, чтобы узнать, сколько байтов действительно написано и прочитано? Вы также можете добавить отладочный вывод в свой код, используя что-то вроде 'fprintf (stderr, ...);' чтобы узнать, что делает ваш код на самом деле. –

+0

Да, я тоже сделал это для чтения. Я попытаюсь каким-то образом отладить его. –

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