Linux上fifos的怪异行为 [英] Weird behaviour of fifos on linux

查看:85
本文介绍了Linux上fifos的怪异行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm studying linux fifos and I made two small C programs which communicate through fifo. The first one acts like a server, it receive a pattern and executes a command using that pattern. The second one acts like a client, it sends the pattern and receive the result. I want the server to be capable of serving multiple requests, not necessarily simultaneously, but the weird thing is that after the first client is served it just stops although I put there an infinite loop.

server.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;
}

client.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(只要有一个写入器,读取器(服务器)就可以).

When the first client closes the FIFO, the server gets EOF on the FIFO, and continues to get no new data in perpetuity. The server has to reopen the FIFO for the next client. If there were multiple clients all with the FIFO open concurrently, the server would not get EOF until the last of the clients disconnected (as long as there is one writer, the reader — the server — will be OK).

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

This is expected behaviour — or, since you weren't expecting it, is the behaviour that should be expected.

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

Of course, since your code completely ignores the return value from read(), you have no idea what, if anything, is being read.

代码:

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

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

is curious; why would you send a buffer of 50 0 bytes to the client? You could perfectly well close the FIFO without sending that.

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

Also note that writing on a FIFO where there isn't a reader will generate a SIGPIPE signal — and you aren't handling those. The default action for SIGPIPE is to exit.

这篇关于Linux上fifos的怪异行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆