Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使服务器进程等待FIFO的第二次读取()?_C_Write_Mkfifo - Fatal编程技术网

C 如何使服务器进程等待FIFO的第二次读取()?

C 如何使服务器进程等待FIFO的第二次读取()?,c,write,mkfifo,C,Write,Mkfifo,我的服务器和客户端使用C语言中的两个命名管道(fifo)来回通信,直到服务器收到exit消息。 显然,服务器端在第二次尝试从其FIFO读取()时会阻塞,尽管客户端已成功写入。我认为问题在于服务器尝试read()的速度比客户端能够write()的速度要快 这是服务器: #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include &quo

我的服务器和客户端使用C语言中的两个命名管道(fifo)来回通信,直到服务器收到
exit
消息。 显然,服务器端在第二次尝试从其FIFO读取()时会阻塞,尽管客户端已成功写入。我认为问题在于服务器尝试
read()
的速度比客户端能够
write()
的速度要快

这是服务器:

#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include "header.h"
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>

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

        //fifo for the server to read from
        if (mkfifo(FIFONAME, S_IFIFO|0666) < 0) {
                if (errno != EEXIST) {
                        perror("Error with mkfifo");
                        exit(1);
                }
        }

        int f;
        if ((f = open(FIFONAME, O_RDONLY)) < 0) {
                perror("Error with open");
                exit(1);
        }

        Message msg;

        while(1) {
                if ((read(f, &msg, sizeof(Message))) > 0) {
                        if (strcmp(msg.user, "exit") == 0) {
                                close(f);
                                unlink(FIFONAME);
                                exit(0);
                        }
                        if (strcmp(msg.user, "new client") == 0) {
                        switch (fork()) {
                                case -1:{
                                        perror("Error with fork");
                                        exit(1);
                                        }
                                case 0:{
                                        char gender[MAXLEN];
                                        char client_fifo[30];
                                        sprintf(msg.user, "I need client's gender\n");
                                        sprintf(client_fifo, "fifo_%d", msg.pid);
                                        msg.pid = getpid();
                                        int o;
                                        //open client's fifo for server to write to
                                        if ((o = open(client_fifo, O_WRONLY)) == -1) {
                                                        perror("Error opening client fifo");
                                                        exit(1);
                                                        }
                                        //send message
                                        write(o, &msg, sizeof(Message));
                                        //read client's answer, but program blocks here
                                        if ((read(f, &msg, sizeof(Message))) > 0) {
                                                sprintf(gender,"%s", msg.user);
                                                printf("Client's gender is %s\n", gender);
                                        }

                                        close(o);
                                        exit(0);
                                       }
                        }
                        }
                }
        }

        return 0;
}


我需要像这样写更多的来回消息,但我不知道如何让服务器在第二次调用
read()

时不阻塞。在父进程和子进程中,服务器中都有相互竞争的
read
调用。在
fork
之后,两个进程都将竞相执行
read
调用以获取数据。在客户端写操作之后先运行的哪个进程将获胜,而另一个进程将阻塞。@kaylum我需要分叉,以便在不同的进程中并行地为连接到服务器的每个客户端提供服务。
fork
之后的
read
应该只被子进程看到,这就是我使用用例的原因。你理解我的第一条评论吗?父进程和子进程都调用
read
,因此它们将争夺相同的数据。只有一个fifo,从一个进程读取它将导致另一个进程无法获取数据,从而阻塞。“fork后读取”是一个模棱两可的短语,因为fork后有多个读取。在fork之后,有两个进程正在执行,其中一个在while循环中,以
read
开头,而
read
发生在fork之后。让家长等待。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include "header.h"
#include <unistd.h>

int f,fc;
char fifoname[20];
Message msg;

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

        sprintf(fifoname, "fifo_%d", getpid());
        if (mkfifo(fifoname, S_IFIFO | 0666) < 0) {
                perror("Error with client's fifo");
                printf("Could not create fifo_%d", getpid());
                exit(1);
        }
        if ((f=open(FIFONAME,O_WRONLY))<0) {
                perror("Error connecting to server");
                exit(2);
        }

        char gender[MAXLEN];
        strcpy(msg.user, "new client");
        msg.pid = getpid();
        //first message to server
        write(f, &msg, sizeof(msg));

        char arg[MAXLEN];
        if (argc > 1) {
                strcpy(arg, argv[1]);
        } else {
                strcpy(arg, "work");
        }
        if (strcmp(arg, "exit")) {

                if ((fc = open(fifoname, O_RDONLY))<0) {
                        perror("Error opening client's fifo");
                        printf("Could not open my fifo");
                        exit(3);
                }
                if (read(fc, &msg, sizeof(msg)) > 0) {
                        printf("%s\n",msg.user);
                }
                scanf("%s", gender);
                strcpy(msg.user, gender);
                msg.pid = getpid();
                printf("writing gender...\n");
                write(f, &msg, sizeof(msg));
                //program successfully reaches this print:
                printf("gender written\n");
                close(fc);
        }
        unlink(fifoname);
        close(f);
        exit(0);
}
#define MAXLEN 20
typedef struct {
    int pid;
    char user[MAXLEN];
} Message;

#define FIFONAME "fifo_server"