用于写入的打开FIFO返回“没有这样的设备或地址”

时间:2017-04-13 21:28:19

标签: c select fifo named

我想创建一个服务器进程和一个客户端进程 - 用于可选的类赋值 - 并使它们相互通信。教授告诉我们:

1)我们必须使用O_NONBLOCK

2)我们必须创建2个FIFO,一个用于只读,一个用于只写

3)我们不能使用套接字

所以,我在服务器进程中创建了2个FIFO,我试图打开它们,但是对于WRONLY打开了“没有这样的设备或地址”。

服务器进程:

......

if( mkfifo("fifo1", PERMS) < 0 && errno != EEXIST)
{
    perror("can't create FIFO (read)");
    exit(EXIT_FAILURE);
}
if( mkfifo("fifo2", PERMS) < 0 && errno != EEXIST )
{
    perror("can't create FIFO (write)");
    exit(EXIT_FAILURE);
}

if( (readfd = open("fifo1", O_RDONLY | O_NONBLOCK)) < 0)
{
    perror("console: can't open read FIFO");
    exit(EXIT_FAILURE);
}
if( (writefd = open("fifo2", O_WRONLY | O_NONBLOCK)) < 0)
{
    perror("coord: can't open write FIFO");
    exit(EXIT_FAILURE);
}

客户流程:

.....

if( (readfd = open("fifo2", O_RDONLY | O_NONBLOCK)) < 0)
{
    perror("console: can't open read FIFO");
    exit(EXIT_FAILURE);
}
if( (writefd = open("fifo1", O_WRONLY | O_NONBLOCK)) < 0)
{
    perror("console: can't open write FIFO");
    exit(EXIT_FAILURE);
}

while( fgets(buffer, 100, stdin) )  //char buffer[100];
{
    n = strlen(buffer);
    w = write(writefd, buffer, n);

    memset(buffer, 0, 100);
}

我在网上找了一个解决方案,然后我找到了this的答案,这解释了出错的原因,但没有提出解决问题的方法。我再次在网上找到了 select(),看起来它可以提供一个解决方案,但我在理解它是如何工作方面遇到了一些麻烦。

是否可以使用 select()来解决此问题?

2 个答案:

答案 0 :(得分:1)

一个简单的解决方案是open fifo用于以阻塞模式写入(它将阻塞直到另一端打开以进行读取),然后使其无阻塞:

    writefd = open(fifo_name, O_WRONLY);
    fcntl(writefd, F_SETFL, O_NONBLOCK);

PS:我强烈建议您不要等待。

答案 1 :(得分:0)

除非读卡器已打开FIFO,否则无法打开FIFO进行无阻塞写入。最简单的解决方法是等待一秒钟,如果它返回open则重复ENXIO。重复直到另一侧正在运行。