【问题标题】:Connecting output of one pipe to input of one FIFO将一根管道的输出连接到一个 FIFO 的输入
【发布时间】:2019-01-22 13:54:01
【问题描述】:

我正在尝试编写一个客户端-服务器程序,其中有三个可执行文件 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。所以它可以作为客户端特定的先进先出。

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?

另外,如果另一个客户端请求D1,如何将client2的文件描述符连接到fd,以便两个客户端一起接收相同的消息?

【问题讨论】:

    标签: unix pipe client-server fifo


    【解决方案1】:

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

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

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


    或者,而不是使用popen

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

    【讨论】:

    • 这当然是一个有效的解决方案,但如果我不想使用套接字怎么办?
    • @Ricky 是什么阻止了您使用 UNIX 套接字?
    • 其实我正在上计算机网络的入门课程,而套接字还没有被介绍。这个问题是一个作业:)
    • @Ricky 在这种情况下,服务器必须从 popen 文件描述符中读取并写入客户端的 fifo。
    • @Ricky 为您添加了另一种方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    • 2012-03-11
    • 2013-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    相关资源
    最近更新 更多