繁体   English   中英

Linux上fifos的怪异行为

[英]Weird behaviour of fifos on linux

我正在研究linux fifos,我制作了两个通过fifo进行通信的小型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;
}

客户端

#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;
}

如果没有阅读器,则对管道进行写操作将使您获得SIGPIPE。 您需要让服务器打开管道进行读取,因此有一个读取器(它不读取任何内容,但是存在)。

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

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

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

编码:

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

很好奇 为什么要发送50 0字节的缓冲区给客户端? 您可以完全关闭FIFO而无需发送它。

还要注意,在没有读取器的FIFO上进行写入将生成SIGPIPE信号-而您不会处理这些信号。 SIGPIPE的默认操作是退出。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM