客户端读取空行

问题描述 投票:0回答:1

[我的Client.c请求用户输入,并将其写入到称为ask.me的oracle.c的FIFO中。当我的oracle.c正在等待读取某些内容时。如果客户端写了一些东西,oracle会读取它并在客户端的fifo中写一个答案,即答案(客户端的pid)。客户端等待,读取答案并将其推出。

一切正常,直到客户必须阅读并给出答案。因为客户端总是出空行,所以我不知道oracle是否不写任何东西,或者客户端无法读取它。

请帮助

ORACLE.c

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

#define FIFO "/tmp/ask.me"



int isVokal(const char* buf, int i){

    if (buf[i] == '?' && ((buf[i-1] == 'a') || (buf[i-1] == 'e') ||(buf[i-1] == 'i') || (buf[i-1] == 'o') || (buf[i-1] == 'u')))
        return 1;
    else
        return 0;
}

char *adress(const char *buf){

    char tmp[500];
    char adress[500] = "/tmp/answer.";
    int i = 0;
    while(buf[i] != ':'){

        tmp[i] = buf[i];
            i++;
    }

    strcat(adress, tmp);
    puts(adress);
    return adress;
}


int answer(char * buf){
    int i = 0;


    int fd = open(adress(buf), O_WRONLY | O_NONBLOCK );
    char *answer = malloc(PIPE_BUF);

    do{
        i++;
        if(buf[i] == '\0'){
            --i;
            if(buf[i] != '?'){

                sprintf(answer, "%s","Dies ist keine Frage.\n");
                write(fd,answer, PIPE_BUF);
                i++;
            }else if(isVokal(buf,i)){

                sprintf(answer, "%s","Yes!\n");
                write(fd,answer, PIPE_BUF);
                i++;
            }else{

                sprintf(answer, "%s","No!\n");
                write(fd,answer, PIPE_BUF);
                i++;
            }
        }

    }while ( buf[i] != '\0');
    free(answer);
    close (fd);
    return 0;
}

void oracle() {

    int i = 1;
    char *buf;
    buf = malloc(PIPE_BUF);

    if ((mkfifo(FIFO, 0666)) == -1)
        perror(" oracle mkfifo:");


    int fd = open(FIFO, O_RDONLY );
    if(fd == -1)
        perror(" oracle open():");


    while (i) {

    printf("waiting for input\n");
        int n = read(fd, buf, PIPE_BUF);

        if (n == -1) {
            perror(" oracle read():");
            exit(EXIT_FAILURE);
        }else{

            i=answer(buf);
        }
        sleep(2);
    }
    free(buf);
    close(fd);
}


int main(){

    oracle();
    return 0;
}

CLIENT.c

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

#define FIFO "/tmp/ask.me"


void question(){
    id_t pid = getpid();
    int fd2,fd;
    char *quest = malloc(PIPE_BUF);
    char *answer = malloc(PIPE_BUF);
    char *buf= malloc(PIPE_BUF);
    char *myID= malloc(PIPE_BUF);
    int n = 0;

    char adress[500] = "/tmp/answer.";
    sprintf(myID, "%d", pid);
    strcat (adress, myID);


    if (mkfifo(adress, 0666) == -1){
        if(errno == EEXIST)
            perror(" oracle mkfifo:");
        else{
            perror(" oracle mkfifo:");
            exit(EXIT_FAILURE);
        }
    }
    fd = open(FIFO, O_WRONLY );
    if(fd == -1){
        perror("client fd open():");
        exit(EXIT_FAILURE);
    }
    while(n==0){
        printf("Bitte Frage stellen\n");
        n=scanf("%s", buf);
    }
    sprintf(quest, "%d :", pid);
    strcat(quest, buf);

    write(fd,quest,PIPE_BUF);
    close(fd);
    sleep(5);
    fd2 = open(adress, O_RDONLY|O_NONBLOCK);
    if(fd2 == -1){
        perror("client fd2 open():");
        exit(EXIT_FAILURE);
    }

    while(1) {
        n=read(fd2, answer, PIPE_BUF);
        if (n == -1) {
            perror(" client read():");
            break;
        } else{
            puts(answer);
            break;
        }
        sleep(2);

    }
    free(quest);
    free(answer);
    free(buf);
    free(myID);

    close(fd2);
    unlink(adress);
}

int main(){

    question();
    return 0;

}
c pipe fifo mkfifo
1个回答
0
投票

这里有很多问题:

  1. [return adress;返回一个立即变为悬空的指针,因此使用它是未定义的行为。
  2. 您在CLIENT.c中的:之前传递了多余的空格,因此ORACLE试图打开错误的文件名。
  3. 仅通过打开O_NONBLOCK来打开FIFO以进行读取。如果您尝试用ENXIO打开它,并且它没有读取器,它将失败,并显示O_WRONLY
  4. 如果尚无要读取的数据,从O_NONBLOCK打开的文件中读取将失败,并以EWOULDBLOCK读取。

修复所有这些问题,您的客户端程序将可以打印Dies ist keine Frage.

顺便说一下,您在CLIENT.c中的sleep(2);将永远不会运行,并且通常在要传输的数据之后读取和写入一堆未初始化的垃圾。

© www.soinside.com 2019 - 2024. All rights reserved.