c - Linux 上 fifos 的奇怪行为

标签 c linux fifo

我正在研究 linux fifos,我制作了两个通过 fifo 进行通信的小 C 程序。第一个就像一个服务器,它接收一个模式并使用该模式执行命令。第二个就像客户端一样,它发送模式并接收结果。我希望服务器能够处理多个请求,不一定同时处理,但奇怪的是,在为第一个客户端提供服务后,它就停止了,尽管我在那里设置了一个无限循环。

服务器.c

#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>


void siginthandler(int i){
    remove("./fifo1");
    remove("./fifo2");
    printf("Got SIGINT signal\n");
    exit(EXIT_SUCCESS);
}


int main(int argc, char *argv[]){
    signal(SIGINT, siginthandler);
    int f = mkfifo("./fifo1", 0600);
    if (f == -1){
        perror("Unable to create fifo1\n");
        exit(EXIT_FAILURE);
    }
    f = mkfifo("./fifo2", 0600);
    if (f == -1){
        perror("Unable to create fifo2\n");
        exit(EXIT_FAILURE);
    }
    int fd1 = open("./fifo1", O_RDONLY);
    int fd2 = open("./fifo2", O_WRONLY);
    if (fd1 == -1 || fd2 == -1){
        perror("Unable to open fifos\n");
        exit(EXIT_FAILURE);
    }
    while (1){
        char buf[50];
        char pattern[50];
        read(fd1, pattern, 50);
        char command[80] = "ps -e | grep ";
        strcat(command, pattern);
        FILE *result = popen(command, "r");
        while (fgets(buf, 50, result)){
            write(fd2, buf, 50);
            //printf("%s", buf);
        }
        memset((void *) buf, 0, 50);
        write(fd2, buf, 50);
        pclose(result);
    }
    remove("./fifo1");
    remove("./fifo2");
    return 0;
}

客户端.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char *argv[]){
    int fd1 = open("./fifo1", O_WRONLY);
    int fd2 = open("./fifo2", O_RDONLY);
    if ((fd1 == -1) || (fd2 == -1)){
        perror("Unable to find fifos");
        exit(EXIT_FAILURE);
    }
    char input[50];
    printf("Give pattern: ");
    scanf("%s", input);
    write(fd1, input, 50);
    char buf[50];
    while (read(fd2, buf, 50) == 50){
        if (buf[0] == 0){
            break;
        }
        printf("%s", buf);
    }
    return 0;
}

最佳答案

当第一个客户端关闭 FIFO 时,服务器会在 FIFO 上获取 EOF,并且永远不会继续获取任何新数据。服务器必须为下一个客户端重新打开 FIFO。如果有多个同时打开 FIFO 的客户端,服务器将不会收到 EOF,直到最后一个客户端断开连接(只要有一个写入器,读取器 - 服务器 - 就可以了)。

这是预期的行为 — 或者,因为您没有预料到它,所以是应该预期的行为。

当然,由于您的代码完全忽略了 read() 的返回值,因此您不知道正在读取什么(如果有的话)。

代码:

memset((void *) buf, 0, 50);
write(fd2, buf, 50);

很好奇;为什么要向客户端发送 50 0 字节的缓冲区?您完全可以在不发送的情况下关闭 FIFO。

另请注意,在没有读取器的 FIFO 上写入会生成 SIGPIPE 信号——而您并未处理这些信号。 SIGPIPE 的默认操作是退出。

关于c - Linux 上 fifos 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17776370/

相关文章:

C:为什么从命令行获取字符串比在程序中设置字符串更容易被识别?

linux 命令 "file"显示 "for GNU/Linux 2.6.24"

linux - 如何配置服务器从外部访问mysql

python - 使用并行运行 html2text

c - 如果使用 IOCP 进行基本信号传输,传递给 CreateIoCompletionPort 的句柄是什么?

c - 与 FIFO 通信的两个程序使用 for 循环但不使用 while 循环

C 预处理器错误

c - 随机数(加法游戏)问题

c - 哈希表和 BST 实现

java - 队列元素乱序排列,不按顺序排列