从命名管道、C 程序(编写器)和 Python(读取器)获取额外数据

Posted

技术标签:

【中文标题】从命名管道、C 程序(编写器)和 Python(读取器)获取额外数据【英文标题】:Getting extra data from named pipe, C program (writer) and Python (reader) 【发布时间】:2018-04-16 15:01:32 【问题描述】:

我有一个 C 程序正在写入一个命名管道,它只是输出字符串和一个“/n”字符作为分隔符。当我使用另一个 C 程序从这个命名管道中读取时,我的字符串按预期返回。我有一个 python 脚本,我想用它来读取命名管道。它得到了正确的字符串,但也输出了许多其他车库数据,包括设备描述符。

编辑:我应该注意我正在使用 linux 上的命名管道

这是运行良好的 C 程序阅读器:

#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#define MAX_BUF 1024

int main()

    int fd;
    char * myfifo = "/tmp/testpipe";
    char buf[MAX_BUF];


    while(1)
            /* open, read, and display the message from the FIFO */
            fd = open(myfifo, O_RDONLY);
            read(fd, buf, MAX_BUF);
            printf("Received: %s\n", buf);
            close(fd);
        
    return 0;

和python版本:

import os
import errno

FIFO = '/tmp/testpipe'

try:
    os.mkfifo(FIFO)
except OSError as oe:
    if oe.errno != errno.EEXIST:
        raise

while True:
    with open(FIFO) as fifo:
        for line in fifo:
            print('0',line)

我得到的输出是:

('0', 'systime=1523890481 ch=25 LAP=c969d3 err=0 clkn=286140 clk_offset=954 s=-68 n=-55 snr=-13\n')
('0', "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x97\xfav(\xdc\xf7~\xc0\xf3\xd1v\x96\x06\x00\x00,\xdc\xf7~$F\xf8v\x01\x00\x00\x00\xb4e\xd2v\x96\x06\x00\x00\x04\x88\xd2v\xa0\x97\xfav,\xdc\xf7~\x18\xdc\xf7~L\xdd\xf7~ \xdc\xf7~T\xdd\xf7~S\xed\xf7~ \xdc\xf7~\x00\x00\x00\x00\xff\x0f\x00\x00T\xdd\xf7~\xc8\xdc\xf7~\x01\x00\x00\x00P@L\x00\x00\x00\x00\x00D\xb9\xdfv\x00\x00\x00\x00L\xdd\xf7~\x01\x80\xad\xfbT\xdd\xf7~T\xdd\xf7~T\xdd\xf7~T\xdd\xf7~z\xdd\xf7~S\xed\xf7~T\xdd\xf7~S\xed\xf7~\x00\x00\x00\x00\xa0\x97\xfav\xc0\xdc\xf7~\xdc\xed\xd1v\x1d\x05\x00\x00\xc4\xdc\xf7~$F\xf8v\x01\x00\x00\x00$N\xd2v\x1d\x05\x00\x00\x04\x88\xd2v\xa0\x97\xfav\xc4\xdc\xf7~\xc0\xdc\xf7~\xff\xff\xff\xff\xf0\xac\xfav\x04\x88\xd2vT\xfc\xd1v\x06n\x0e\xc4ps \x06\x82\x0b\xf1v\x90\xf5\xf0v0\x89\xf9v\xf0\xac\xfav0\xdd\xf7~\x88\xb8\xfav\xbcr\xf9v\x00\xb0\xfav\x00\x00\x00\x00\x00W\xfav\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf4\xdd\xf7~\x06n\x0e\xc4\xd0\x93\xfav\x00\x00\x00\x000\xdd\xf7~8\xdd\xf7~\xa4\xdd\xf7~\x82\x0b\xf1v\x8c\xdd\xf7~\xfcK\xf8v8\xdd\xf7~\xbc\xba\xfav\x05\x00\x00\x00XX\xfav\x05\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x18\x92\xfav\xe8\xac\xfav\xff\xff\xff\xff\x00\x00\x00\x00T\xdd\xf7~\x00\x00\x00\x00\xff\xff\xff\xff\xd0\x93\xfav\x18\x92\xfav\xff\xff\xff\xffp\xcc\xddv$N\xd2v\xa0\x97\xfav\xe0\x13\xf2v\xc8\x13\xf2v |M\x00\xd4 \xf2vD[\xe5v/sys\x00\x00\x00\x00/usb/devices/1-1\x00\xf0\xf0vl@\x02\x00\x01\x00\x00\x00`d\xfav\x00\x00\x00\x00P@L\x00\xf8\xdd\xf7~\x0c\x00\x00\x00\xe8\xa1\xf8vXX\xfav\x01\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00/1-1$N\xd2v \xcaM\x00\x02\x00\x00\x00\xe8\xac\xfav \xcaM\x00\xf4\xdd\xf7~\xe8\xac\xfav\t\x00\x00\x00\x00\x00\x00\x00P@L\x00p\xcc\xddv\xcc\x9c\xf1v\x02\x00\x00\x00t\x14\xf2v\xd0\x1d\xf2v\x01\x00\x00\x00\x04\x00\x00\x00\x1c\x00\x00\x00\x15\x00\x00\x01\x0c\xf5\xf8'/dev/bus/usb/001/004\x00\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")

这两个程序从命名管道读取有什么区别?

【问题讨论】:

我猜你编写的 C 程序有一个错误,就像你在这里展示的阅读 C 程序一样。您需要检查所有 c 函数的返回码 open read 等,否则可能会打印未初始化缓冲区的值。我还怀疑您正在使用终止字符之后出现的任何垃圾写入整个缓冲区。 while True: ????请发minimal reproducible example。 @Stargateur while True 如果 FIFO 可以关闭但稍后会提供更多数据,则非常有意义 @user234461 是的,超级,一切都说得通,但你在实际代码中看到类似的东西吗?不。我们不应该假设不存在的代码。 总是,总是,检查像read这样的函数的返回值。当打印从非字符串函数接收到的数据时(比如这里的read),请始终确保您指定正确的数据长度(这里由read 返回!),或者确保那里有字符串终止的空值(您仍然需要read 的返回值来执行此操作)。 【参考方案1】:

C 将\x00(NUL 字符)识别为字符串的结尾(请参阅:c-string),但 Python 不会。垃圾总是存在于 FIFO 中,因此基于 C 的编写器出于某种原因将垃圾发送到 FIFO(我们永远不会知道,因为您尚未发布该代码)。

【讨论】:

我投票结束这个问题。我有一个类似的问题,而 OP 对回答您的问题没有兴趣,这使他的问题成为错误的线索。

以上是关于从命名管道、C 程序(编写器)和 Python(读取器)获取额外数据的主要内容,如果未能解决你的问题,请参考以下文章

写和读命名管道

ifstream 管道和多个(顺序)编写器

将子进程的 stdout 和 stderr 重定向到两个命名管道(然后从它们读回)

在断开连接之前等待读取命名管道

C 到 Python 管道 - 如何检测读取器访问

检测命名管道的关闭