写入/读取FIFO文件 - linux

时间:2014-05-02 17:38:07

标签: c linux posix fifo

我一直试图绕过FIFO,想出了一个简单的服务器和客户端程序。
我没有尝试做任何花哨的事情,只是为了让一个过程能够扮演“服务器”的角色,这个过程将会聆听'对另一个进程传递的任何消息;客户。
这是我写的:

server.c

#include<stdio.h>
#include <fcntl.h>
#include <stdlib.h>


#define INGOING "clientToServer.fifo"

#define BUFFER 200

int main(int argc, char *argv[]) {

    char in[BUFFER];

    mkfifo(INGOING, 0666);

    printf("Welcome to server.\n");
    printf("channel for sending messages to server is %s\n", INGOING);

    int in_fd=open(INGOING, O_RDONLY);

    if (in_fd==-1) {
        perror("open error");
        exit(-1);
    }

    while (read(in_fd, in, BUFFER)>0) {
        printf("You sent %s to server.\n", in);
    }

    return 2;
}

正如你所看到的,这是非常简单的,当我在./server.out& read来电时阻止clientToServer.fifo来阻止任何人写信{{1} }}。到目前为止一切顺利。

现在,考虑客户端:
client.c

#include<stdio.h>
#include<fcntl.h>
#include<string.h>


#define BUFFER 200

int main(int argc, char *argv[]) {

    char input[BUFFER]={0};
    int out_fd=open("clientToServer.fifo", O_WRONLY);

    if (out_fd==-1) {
        perror("open error");
    }

    while (1) {

        printf("What would you like to send to server? (send Quit to quit)\n");
        fgets(input, BUFFER, stdin);
        if (input[strlen(input)-1]=='\n') {
            input[strlen(input)-1]='\0';
        }

        if (strcmp(input, "Quit")==0) {
            printf("Bye!");
            break;
        }

        if (write(out_fd, input, strlen(input))==-1) {
            perror("write error");
        }
    }

    return 1;
}

这是客户。也很简单的代码。当我使用./a.out从shell运行它时,它可以工作 - 它发送消息,server.out进程打印You sent %s to server.
问题是,当我通过客户端向服务器发送Quit时,虽然a.out进程会根据需要终止,但while中的server.out循环也会中断。意思是,read不再阻止server.out进程并等待其他客户端,而是服务器程序与客户端一起结束。
为什么会这样?即使在read流程结束后,server.out再次暂停a.out 也不应该吗?

2 个答案:

答案 0 :(得分:9)

  

当我使用./server.out&在后台运行它时它在读取调用时被阻止并等待任何人写入clientToServer.fifo

实际上它会阻挡open。这是FIFO工作的方式。 open(在阻塞模式下)将阻塞,直到某些东西在另一端打开FIFO。

  

server.out中的while循环也会中断。意思是,read不再阻塞server.out进程并等待其他客户端,而是服务器程序结束

同样,这是正常行为。只有一个客户端进程连接到FIFO,因此当它关闭时,则发送EOF并退出服务器。如果多个客户端同时连接到FIFO,则在最后一个客户端关闭EOF之前,您不会看到EOF。如果您希望长时间运行的服务器连续为多个客户端提供服务,最简单的方法是将服务器的FIFO打开为读/写。这种方式总是有一个读写器 - 服务器本身 - 即使最后一个客户端退出也不会看到EOF。什么时候关闭服务器然后关闭服务器中的适当的一端,让大自然在真正的客户退出时采取自己的方式。

答案 1 :(得分:2)

当客户端退出时,它会关闭管道连接,这会导致服务器中的read函数返回退出循环的0