将一个管道的输出连接到一个 FIFO 的输入

Connecting output of one pipe to input of one FIFO

我正在尝试编写一个客户端-服务器程序,其中包含三个可执行文件 D1、D2 和 D3,它们提供一些数据作为输出。客户端请求这些数据源中的任何一个,并在公共 fifo 的帮助下将它们的 pid 发送到服务器。发送这个请求的结构是:

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,Server会运行:

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 吗?

另外,如果另一个client请求D1,如何将client2的文件描述符连接到fd,使两个client同时收到相同的消息?

代替"connecting"两个文件描述符,可以将文件描述符发送给客户端,让客户端读取:

  1. 服务器侦听 UNIX 流套接字。
  2. 客户端连接套接字并发送请求。
  3. 服务器收到请求,popen获取文件描述符。
  4. 服务器然后将文件描述符发送给客户端并关闭文件描述符。
  5. 客户端接收文件描述符并从中读取直到 EOF。

有关使用 SCM_RIGHTS 在进程之间发送文件描述符的详细信息,请参阅 man unix(7)


或者,不使用 popen:

  1. 服务器fork本身。 child 执行 mkfifo(客户端在请求中传递了文件名),open 将其写入并将其 stdout 重定向到命名管道的文件描述符中。
  2. child exec 应用程序。此应用程序写入 stdout 并进入命名管道。
  3. 客户端打开命名管道并读取应用程序的输出。客户端打开后可以unlink管道文件名。