我需要构建两个程序:C中的服务器和客户端,它们实现以下功能:
服务器收到该消息,然后将该消息传递给在屏幕上打印消息的子节点(使用匿名管道)。
我现在遇到的问题是当只有一个连接的客户端时,有时孩子会阅读并打印TWICE信息。
我已经在这里待了8个小时了,我无法理解这一点。请有人帮我这个,我在这里疯了。这是我到目前为止的代码:
客户端
int main(int argc, char* argv[]){
int pPedido;
pPedido = open("pedido",O_WRONLY);
char buffer[6] = "ABCDE";
write(pPedido,buffer,6);
printf("FECHOU\n");
return 0;
}
服务器
int main(int argc, char* argv[]){
int exists = 0;
int pipeID[2];
int pPedido;
char buffer [100];
mkfifo("pedido",0666);
while(1){
pPedido = open("pedido",O_RDONLY);
read(pPedido,buffer,6);
if(exists == 1){
write(pipeID[1],"ABC",4);
}
else{
pipe(pipeID);
if(fork() == 0){
char bufferzito[100];
while(1){
read(pipeID[0],bufferzito,4);
printf("%s\n",bufferzito);
}
}
else{
write(pipeID[1],"ABC",4);
exists = 1;
}
}
}
return 0;
}
这些是我使用的包含。我认为其中有些不是必要的。
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
答案 0 :(得分:0)
您没有检查open
或read
的返回值。这两个函数都可以返回-1表示错误。
可能发生的事情是,在服务器while循环的第二次迭代中,open或read立即返回,返回值为-1(错误),因此循环再次执行。
调用read或open后,检查返回值,并检查errno是否返回-1。
你也会在循环的每次迭代中反复打开相同的fifo,而不会关闭它。
答案 1 :(得分:0)
我已经测试了以下解决方案,但它确实有效。
问题似乎是客户端在没有关闭管道的情况下退出。
不知何故,这导致第二次读取将0字节写入缓冲区。根据文档,将0
作为read
的返回值意味着EOF
。我不确定为什么在第一次客户端连接时我们没有得到第二次读取。
要处理这种情况,您可以执行以下两项操作之一。你可能应该同时做这两件事。
在服务器端检查读取呼叫的返回值
...
int n = read(pPedido,buffer,6);
if(n==0) continue;
...
在客户端关闭管道,然后退出
...
printf("FECHOU\n");
close (pPedido);
return 0;
任何一方本身都可以解决问题。但我建议同时做这两件事。