从命名管道读取 [英] read from a named pipe

查看:59
本文介绍了从命名管道读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须实现一个打印服务器".我有 1 个客户端文件和 1 个服务器文件:

I have to implement a "printing server". I have 1 client file, and 1 server file:

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

int get_line( char *dest, int size );

#define MAX 1024

void main ()
{
    char const *pipe = "printservers";
    char buffer[MAX];
    int fd;

    get_line( buffer, MAX );

    if( mkfifo( pipe, 0666 ) < 0 )
    {
        printf( "Cannot create a pipe\n" );
        exit( EXIT_FAILURE );
    }

    fd = open( pipe, O_WRONLY );

    write( fd, buffer, MAX );

    close( fd );

    //unlink( pipe );

}

int get_line( char *dest, int size )
{
    int c, i;
    for( i = 0; i < size - 1 && ( c = getchar() ) != EOF && c != '\n'; ++i )
        dest[i] = c;
    if( c == '\n' )
    {
        dest[i] = c;
        ++i;
    }
    dest[i] = '\0';
    return i;
}

这是客户端,它从标准输入中读取一行并写入一个命名管道称为打印服务器.这按预期工作.

This is the client, which reads from the standard input a line and writes into a named pipe called printservers. This works as intended.

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

#define MAX_BUF 1024
#define MAX_PID 8

int main()
{
    int fd;
    char * myfifo = "printservers";
    char buf[MAX_BUF];

    /* open, read, and display the message from the FIFO */
    fd = open( myfifo, O_RDONLY );
    while( 1 )
    {
        if( read( fd, buf, MAX_BUF ) > 0 )
            printf("Received: %s\n", buf);
    }
    close(fd);

    return 0;
}

这是从管道中读取的服务器.但它不适用于 while 循环.如果我从客户端发送消息,则打印第一条消息,但忽略以下消息.有人可以帮我解决我的问题吗?谢谢帕特里克

This is the server, which are read from the pipe. But it does not work with the while loop. If i send a message from the client, the first message is printed, but the following messages are ignored. Could somebody help me with my problem? Thanks Patrik

推荐答案

服务器的 while 循环中存在编码错误 - 即使出现错误或服务器在 FIFO 上收到 eof,服务器也永远不会退出循环.应该改成这样:

There is a coding error in the server's while loop - the server will never exit the loop even when there is an error or the server receives eof on the FIFO. It should be changed to something like this:

while(1)
{
    if((bytesread = read( fd, buf, MAX_BUF - 1)) > 0)
    {
        buf[bytesread] = '\0';
        printf("Received: %s\n", buf);
    }
    else
        break;
}

您的另一个问题是您的客户端发送了一行,然后关闭了 FIFO.服务器读取直到EOF.所以它将读取单行,然后因为客户端关闭而点击 EOF.这是完全正常的.

Your other problem is that your client sends a single line and then closes the FIFO. The server reads until EOF. So it is going to read the single line, then hit EOF because the client closed. This is completely normal.

当您希望您的服务器为多个客户端提供服务时,就会出现问题.在这种情况下,您不想在每个单独的客户端结束后停止阅读.语义是这样的,服务器只会在 所有 客户端的最后一个关闭后看到 EOF.因此,容纳处理多个客户端的服务器的一种简单方法是将服务器端 FIFO 以读/写方式打开.然后总会有一个写入器",即服务器本身,FIFO 的写入端打开.这将防止服务器看到 EOF,直到您决定将其关闭.

Where it becomes a problem is when you want your server to provide service to multiple clients. In that case you don't want to quit reading after every individual client closes its end. The semantics are such that the server will only see EOF after the last of all clients close. So an easy way to accommodate the server handling multiple clients is to open your server-side FIFO as read/write. Then there will always be a "writer", the server itself, with write end of the FIFO open. This will prevent the server from seeing EOF until you decide to shut it down.

第二个问题是你需要循环读写.您不能保证在一次调用中就获得完整的数据请求.

A second problem is that you need to read and write in loops. You are not guaranteed to get your full data request filled in one call.

此外,让客户端创建服务器读取的 FIFO 是一种奇怪的方法.通常,您希望服务器创建一个客户端连接的已知 FIFO.

Also, having the client create the FIFO that the server reads is an odd approach. Normally you want the server to create a known FIFO to which clients connect.

这篇关于从命名管道读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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