#c #unix #fifo
#c #unix #fifo
Вопрос:
Я хочу использовать пару Unix FIFO таким образом, чтобы:
- клиент отправляет на сервер имя файла и
- сервер возвращает клиенту: количество слов, строк и байтов из заданного файла.
Не могли бы вы, пожалуйста, помочь?
client.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int nr,s2c,c2s,c,d,e;
char a[20];
c2s=open("fifo1",O_WRONLY);
s2c=open("fifo2",O_RDONLY);
printf("give file name n");
scanf("%s",a);
nr=strlen(a);
write(c2s,amp;nr,sizeof(int));
write(c2s,amp;a,sizeof(nr));
read(s2c,amp;c,sizeof(int));
read(s2c,amp;d,sizeof(int));
read(s2c,amp;e,sizeof(int));
close(c2s);
close(s2c);
return 0;
}
server.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int nr,s2c,c2s,c,d,e;
char a[20];
FILE* f;
c2s=open("fifo1",O_RDONLY);
s2c=open("fifo2",O_WRONLY);
read(c2s,amp;nr,sizeof(int));
read(c2s,amp;a,sizeof(nr));
f=fopen(a,"r");
if(fork()==0)
{
printf("result is: n");
execl("/usr/bin/wc","wc",c,d,e,NULL);
}
wait(0);
write(s2c,amp;c,sizeof(int));
write(s2c,amp;d,sizeof(int));
write(s2c,amp;e,sizeof(int));
close(c2s);
close(s2c);
printf("n FINISH n");
return 0;
}
Я внес некоторые улучшения, но все равно это не работает должным образом.
Ответ №1:
В fork
редактируемой части сервера перенаправьте стандартный ввод и вывод wc
с помощью
dup2(c2s, STDIN_FILENO);
dup2(s2c, STDOUT_FILENO);
Затем запустите его с помощью
execl("/usr/bin/wc", "wc", NULL);
Не передавайте файловые дескрипторы в качестве аргументов execl
. Он ожидает строки ( char const*
), а не int
.
Смотрите dup2
в стандарте POSIX, чтобы понять, как это работает.
Комментарии:
1. Не забудьте закрыть дублируемые дескрипторы. Вероятно, в этом примере можно обойтись и без этого, но в целом, хорошо быть аккуратным.
Ответ №2:
Обратите внимание, что wc
записывает строки символов в свой вывод. Вы пытаетесь прочитать их так, как если бы они были двоичными числами. Это приведет к путанице, особенно если вы не проверяете, что вызовы read работали правильно.
На самом деле, общий комментарий — вам следует проверить гораздо больше ваших системных вызовов.
Вы также должны убедиться, что ваши процессы не блокируются при открытии FIFOs. Все должно быть в порядке; у вас есть процессы, открытые ‘fifo1’ для чтения и записи, а затем ‘fifo2’. Я думаю, что это приводит к правильному порядку вещей.
В канале правильно записываются только 4-буквенные имена файлов.