c - Wie prüfe ich EOF wenn read () auf FIFO

In einem Client-Server-Programm muss @ überprüft werde EOF zumread() auf einenFIFO?

Fragen

Tut EOF im FIFO return0, oder-1 mit errno gesetzt? Gilt die Regel auch für andere IPC-Einrichtungen?

@Aktualisiere

Ich habe immer noch das Ergebnis gefunden, also muss ich weiter danach fragen.

Folgende sind der Quellcode:

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();
}

Kompilieren

Server:gcc -Wall fifo_server.c -o server

Klient:gcc -Wall fifo_client_pool.c -o client_pool

Ausführen

Erster Start-Server:./server

Dann Client-Pool starten:./client_pool

Ergebnis

Server startet und blockiert vor dem Clientstart.

Wenn der Client gestartet wird und der Server von jedem der drei Clients eine Anfrage erhält, sind dies insgesamt drei.

Dann werden alle Client-Prozesse beendet, dann wird der Server mit read () fortgesetzt. Return0 ohne gesperrt.

Die zukünftige Frage ist:

Nachdem alle Clients beendet wurden, sollte der Server nichtread() Block? Da es im Sperrmodus ist?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage