Соединение выхода одной трубы с входом одного FIFO - PullRequest
0 голосов
/ 22 января 2019

Я пытаюсь написать программу клиент-сервер, в которой есть три исполняемых файла D1, D2 и D3, которые предоставляют некоторые данные в качестве выходных данных.Клиенты запрашивают любой из этих источников данных и отправляют свой pid на сервер с помощью обычного fifo.Структура для отправки этого запроса:

struct Request
{
    char p[10]; // the pid of the client program in string form
    int req; // 1,2,or 3 depending on which one is required D1,D2 or D3
};

После получения запроса сервер откроет fifo, чей путь - это pid клиента.Таким образом, он работает как клиентское fifo.

mkfifo(pid,O_CREAT|0666);
int fd1 = open(pid,O_WRONLY);

Теперь предположим, что поле req равно 1. Если это первый запрос для D1, сервер будет работать:

FILE* fp = popen("./D1","r");
int fd = fileno(fp); //for getting the file descriptor for the reading end of the pipe connected to D1

Теперь я хочу, чтобы мой клиент для чтения из канала D1.D1 содержал простую логическую программу, такую ​​как:

while(1)
{
    write(1,"Data from D1",12);
    sleep(1);
}

Я пытался dup2 (fd, fd1) , ноэто не работает.Есть ли способ соединить два файловых дескриптора fd и fd1?

Кроме того, если другой клиент запрашивает D1, как подключить файловый дескриптор client2 к fd, чтобы оба клиента получали одно и то же сообщение вместе?

1 Ответ

0 голосов
/ 22 января 2019

Вместо «соединения» двух файловых дескрипторов вы можете отправить дескриптор файла клиенту и позволить клиенту прочитать:

  1. Сервер прослушивает потоковый сокет UNIX.
  2. Клиент подключает сокет и отправляет запрос.
  3. Сервер получает запрос, выполняет popen и получает дескриптор файла.
  4. Затем сервер отправляетдескриптор файла клиенту и закрывает дескриптор файла.
  5. Клиент получает дескриптор файла и читает его до EOF.

См. man unix (7) для получения подробной информации об отправке файловых дескрипторов между процессами с SCM_RIGHTS.


В качестве альтернативы, вместо использования popen:

Сам сервер fork s.Дочерний объект mkfifo (клиент передал имя файла в запросе), open s записывает его и перенаправляет stdout в дескриптор файла именованного канала. Ребенок exec с приложением.Это приложение записывает в stdout, и это входит в именованный канал. Клиент открывает именованный канал и читает выходные данные приложения.Клиент может unlink имя файла канала после его открытия.
...