[我的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;
}
这里有很多问题:
return adress;
返回一个立即变为悬空的指针,因此使用它是未定义的行为。:
之前传递了多余的空格,因此ORACLE试图打开错误的文件名。O_NONBLOCK
来打开FIFO以进行读取。如果您尝试用ENXIO
打开它,并且它没有读取器,它将失败,并显示O_WRONLY
。O_NONBLOCK
打开的文件中读取将失败,并以EWOULDBLOCK
读取。修复所有这些问题,您的客户端程序将可以打印Dies ist keine Frage.
顺便说一下,您在CLIENT.c中的sleep(2);
将永远不会运行,并且通常在要传输的数据之后读取和写入一堆未初始化的垃圾。