0

我有两个 C 文件,server.c 和 client.c。服务器必须创建一个 fifo 文件并不断读取它,等待输入。客户端获取它的 PID 并将 PID 写入 fifo。这是我首先启动的服务器文件:

int main(){
  int fd;
  int fd1;
    int bytes_read;
    char * buffer = malloc(5);
    int nbytes = sizeof(buffer);

    if((fd = mkfifo("serverfifo",0666)) == -1) printf("create fifo error");
    else printf("create fifo ok");

    if ((fd1 = open("serverfifo",O_RDWR)) == -1) printf("open fifo error");
    else{
        printf("open fifo ok"); 
        while(1){
            bytes_read = read(fd,buffer,nbytes);
            printf("%d",bytes_read);
            }
        }

return(0);
}

我的客户文件:

int main(){

    int fd;
    int pid = 0;
    char *fifo;
    int bytes;

    if ((pid = getpid()) == 0)  printf("pid error");
    char pid_s[sizeof(pid)];
    sprintf(pid_s,"%d",pid); 


   if ((fd = open ("serverfifo",O_RDWR)) == -1)printf("open fifo error");
   else {
    printf("open fifo ok");

        bytes = write(fd,pid_s, sizeof(pid_s));
        printf("bytes = %d",bytes);

   }

    close(fd);
return(0);
}

我遇到的两个主要问题是:当我将 pid 写入文件时,它返回我写入的字节数,所以看起来没问题,但是当我检查 fifo 文件的属性时,它显示为 0 字节。第二个问题是读取不起作用。如果我在它显示之前执行 printf ,但在它没有显示之后并且读取没有返回任何它只是冻结。我意识到网站上有很多类似的帖子,但我找不到任何有用的东西。我正在使用带有 CodeBlocks 的 Ubuntu 和 GCC 编译器。

4

2 回答 2

3

这里有很多问题

char pid_s[sizeof(pid)];
sprintf(pid_s,"%d",pid); 

sizeof(pid)返回 pid 值的大小,而不是它的字符串表示形式,即它是sizeof(int)4 或 8,具体取决于您的体系结构。然后您继续打印它。如果这行得通,它只能靠运气(你在 64 位机器上)。正确的做法是,如果您选择这样做,则分配一个适当大的缓冲区,并使用 snprintf 确保您不会溢出。PID 适合 5 位数字,因此可以执行以下操作:

char pid_s[8];
snprintf(pid_s, sizeof(pid_s), "%d", pid);

当然,您可以一起跳过这一步,而是发送 pid 的原始字节

write(fd, (void*)&pid, sizeof(pid))

现在在服务器中你犯了类似的错误:

char * buffer = malloc(5);
int nbytes = sizeof(buffer);

sizeof(buffer)再次返回 4 或 8,但您分配了 5 个字节,如果您想在堆上分配(使用 malloc),正确的方法是:

char* buffer = malloc(8);
int nbytes = 8;

或者,您可以在堆栈上分配:

char buffer[8];
int nbytes = sizeof(buffer);

sizeof 有点神奇,因为如果你传入一个数组,在这种情况下它会返回数组的大小 (8*1)。

当你阅读时,你读了 5 个字节,这可能是不够的(因为你写了 8 个字节,因为之前的 bug),所以它不会完成。你应该这样读

int pid;
read(fd, (void*)&pid, sizeof(pid));

此外,如果您要实际读取和写入字符串,您将执行以下操作:

// client
char pid_s[8];
snprintf(pid_s, sizeof(pid_s), "%d", pid);
write(fd, pid_s, sizeof(pid_s));

// server
char pid_s[8];
read(fd, pid_s, sizeof(pid_s));

另请注意,读取返回的内容可能少于写入的内容,您需要再次调用它以继续阅读...

于 2012-12-18T15:30:09.410 回答
0

好吧,这段代码有很多错误......首先 sizeof 不是那样工作的。为什么要序列化 ​​pid ?

这是错误的:

char pid_s[sizeof(pid)];

123456 是一个整数,它不适合这个大小为 4 的数组,只能打印 3 个字符...

而且因为您正在尝试序列化 pid,所以您不知道要读取的预期大小,除非您采取最坏的情况并为 '\0' 写入 10 + 1...

于 2012-12-18T15:28:07.723 回答