【问题标题】:Read / Write through a pipe in C通过 C 中的管道读/写
【发布时间】:2013-01-29 13:47:59
【问题描述】:

我今天开始在 C 中使用 pipe() 和 fork() 和 exec(),现在我遇到了一个问题:

主程序,创建两个管道和分叉。子进程对另一个程序执行 exec(),该程序现在只是一个测试程序,它从标准输入读取,与其父进程通信并通过标准输出写入结果。主程序应该接收数据,与 SQLite 3 数据库通信并使用管道返回数据。这部分问题解决了,管道开合正常,有通讯了。

那么问题是,在某个点的子进程(用exec()调用的那个)中,我有这个:

printf("Strid sent: %s\n", strid);
write(4,strid,sizeof(strid));

printf("Str sent: %s\n", str);
write(4,str,sizeof(str));

家长应该正确阅读这部分内容:

read(select[0],strid, sizeof(strid));
printf("Strid recived: %s\n",strid);
int id = atoi(strid);
printf("Id recived: %d\n",id);

read(select[0],buffer, sizeof(buffer));
printf("Buffer recived: %s\n",buffer);

但我收到的那些 printf 是:

Strid sent: 1
Str sent: start
Strid recived: 1
Id recived: 1
Buffer recived: 7� (and other strange characters)

如您所见,问题在于接收第二个命令(该部分按原样复制,其中没有其他代码)。

我也不得不说,接收str的“buffer”变量被声明为char buffer[20]并且在read()之前没有被使用过

提前谢谢你!

【问题讨论】:

  • strid 和 str 的声明是什么?
  • 如果子进程写入 sizeof(buffer) 字节或更多字节,父进程将一直写入到 0 字节。写入的内容也可能超过 str 中感兴趣数据的长度,您可能应该写入 strlen(str) 字节而不是 sizeof(str)。并且不要忘记终止的 0。
  • 您可能希望在写入函数中使用 strlen 而不是 sizeof。只是好奇,为什么你使用 4 作为文件描述符而不是使用变量?
  • Kjell Andreassen:我意识到现在有了另一个答案,这就是问题所在。谢谢
  • REALFREE:我用4作为fd,因为那部分代码是exec调用的程序,所以不能直接使用变量。我可以将它作为参数传递,但更容易(并且它可以工作),即使这种形式更丑陋(因为我只有两个管道,我可以手动控制它们)

标签: c fork pipe


【解决方案1】:

读完后,需要在最后加上终止0字节,在打印之前,类似

int len = read(select[0], buffer, sizeof(buffer) - 1);
if (len < 0) {
    perror("read error");
} else {
    buffer[len] = 0;
    printf("Buffer recived: %s\n", buffer);
}

所以,重要的是,在使用之前通读man page of read,或者实际上是任何函数的手册页...

或者,使用一些 stdio.h 函数,它自己添加以0 结尾的字符串,如果可以逐行读取,则可能是fgets

【讨论】:

  • 正如 Kjell Andreassen 之前评论的那样,正如您所提到的,尺寸不匹配,我已经使用了几个小时。谢谢
【解决方案2】:

管道不跟踪写入之间的“边界”。因此,如果您在管道上进行了多次写入,则来自这些写入的所有数据都可能会返回以响应一次读取。因此,如果您发送一个字符串(例如)后跟一个整数,并且您尝试将字符串读入缓冲区,它会将字符串和后面的整数整数都放入缓冲区,看起来像字符串末尾的垃圾, read 返回的大小会更大。

此外,如果管道已满,则写入可能不会写入您要求它写入的所有数据——它可能只写入目前可以容纳的数据,而您必须稍后再写入其余数据。

因此,请始终检查您的 readwrite 调用的返回值,并准备好处理比您预期的要少(或多于 read)。

【讨论】:

    猜你喜欢
    • 2011-07-18
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-11
    • 1970-01-01
    相关资源
    最近更新 更多