Ç - 如何检查EOF上FIFO读时() [英] c - How to check EOF when read() on FIFO

查看:132
本文介绍了Ç - 如何检查EOF上FIFO读时()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在客户机 - 服务器程序,需要检查 EOF 阅读()上一个 FIFO

In a client-server program, need check EOF for read() on a FIFO?

问题:


  • 确实 EOF 在FIFO回报 0 1 ,并将errno设置?

  • 是否规则也适用于其他IPC设施?

  • Does EOF in FIFO return 0, or -1 with errno set?
  • Does the rule also apply to other IPC facilities?

@Update

我仍然发现的结果持,所以需要继续问吧。

I still found the result wield, so need to continue ask about it.

cs_fifo.h:

// fifo header
#ifndef _CS_FIFO
#define _CS_FIFO

#define CLIENT_DATA_SIZE 2
#define SERVER_DATA_SIZE 10

#define SERVER_FIFO_PATH "/tmp/server_fifo"

#define CLIENT_COUNT 3

#endif

fifo_server.c:

// client - server fifo, server part,
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "cs_fifo.h"

int fifo_server() {
    int flag;
    int fd;

    char buf[CLIENT_DATA_SIZE];

    // remove fifo, before create
    remove(SERVER_FIFO_PATH);

    // create fifo
    mode_t mode = 0644;
    if((flag = mkfifo(SERVER_FIFO_PATH, mode)) == -1) {
        printf("error while mkfifo(): %s\n", strerror(errno));
        return -1;
    }
    printf("server fifo created, path: %s\n", SERVER_FIFO_PATH);

    // open for read
    if((fd = open(SERVER_FIFO_PATH, O_RDONLY)) == -1) {
        printf("error while open(): %s\n", strerror(errno));
        exit(-1);
    }

    // loop to receive data from client,
    while(1) {
        // read from fifo
        if((flag = read(fd, buf, CLIENT_DATA_SIZE)) == -1) {
            printf("error while read(): %s\n", strerror(errno));
            exit(0);
        } else if(flag == 0) { // no data
            printf("no data\n");
            sleep(1);
            continue;
        }
        // data received,
        printf("receive data: %s\n", buf);

        // send data back to client's fifo,
        // TODO
    }

    // remove fifo, after finish using,
    remove(SERVER_FIFO_PATH);

    return 0;
}

int main(int argc, char * argv[]) {
    return fifo_server();
}

fifo_client.c:

// client - server fifo, client pool part,
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "cs_fifo.h"

int fifo_client_pool() {
    int flag;
    int server_fd;

    char data[CLIENT_DATA_SIZE];

    int i = 0;
    pid_t cpid;
    char identity;

    // open for write
    if((server_fd= open(SERVER_FIFO_PATH, O_WRONLY)) == -1) {
        printf("error while open(): %s\n", strerror(errno));
        exit(-1);
    }

    // create child processes as clients,
    while(i < CLIENT_COUNT) {
        switch(cpid=fork()) {
            case -1: // failed
                printf("error while fork(): %s\n", strerror(errno));
                exit(errno);
            case 0: // success, child process goes here
                printf("child process created, pid [%d], parent pid [%d]\n",(int)getpid(), (int)getppid());
                identity = i + 65; // start from 'A'

                // prepare data
                data[0] = identity;
                data[1] = '\0';

                // write to fifo
                if((flag = write(server_fd, data, CLIENT_DATA_SIZE)) == -1) {
                    printf("[%c] error while write(): %s\n", identity, strerror(errno));
                    _exit(-1);
                }
                printf("[%c] send data to server\n", identity);

                _exit(0);

                break;
            default: // success, parent process goes here
                // sleep a while,
                sleep(1);
                break;
        }

        i++;
    }

    if((flag = close(server_fd)) != 0) {
        printf("error while close(): %s\n", strerror(errno));
    }

    return 0;
}

int main(int argc, char * argv[]) {
    return fifo_client_pool();
}


编译:

服务器:的gcc -Wall -o fifo_server.c服务器

客户:的gcc -Wall -o fifo_client_pool.c client_pool

执行:

首先启动服务器: ./服务器

然后启动客户端池: ./ client_pool

结果:


  • 服务器启动,并阻止客户端开始之前。

  • Server start, and blocks before client start.

然后客户端开始,服务器接收从每个3个客户端​​的1个请求,那就是共3个。

Then client start, and server receive 1 request from each of the 3 clients, that's 3 in total.

然后,所有客户端进程终止,那么服务器的read()返回继续 0 没有阻止。

Then all client processes terminated, then server's read() continue return 0 without blocked.

未来的问题是:


  • 所有客户端终止之后,不应服务器的阅读()阻止?因为它是阻塞模式<?/ li>
  • After all clients terminated, shouldn't server's read() block? Since it's in blocking mode?

推荐答案

所有的从一个描述符,其中返回零读取的意思是封闭或结束。

All reads from a descriptor where read returns zero means "closed" or "end".

如果你有一个阻塞描述符(默认值),那么会,如果有什么当前读阻塞。如果描述符是非阻塞那么收益 1 错误号设置为 EAGAIN EWOULDBLOCK 如果没有什么阅读。。

If you have a blocking descriptor (the default) then read will block if there's currently nothing to read. If the descriptor is non-blocking then read returns -1 with errno set to EAGAIN or EWOULDBLOCK if there's nothing to read.

这篇关于Ç - 如何检查EOF上FIFO读时()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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