如何在 Linux 中的进程之间交换二进制数据

Posted

技术标签:

【中文标题】如何在 Linux 中的进程之间交换二进制数据【英文标题】:How to exchange binary data between processes in Linux 【发布时间】:2011-02-02 10:33:22 【问题描述】:

我需要创建一个 linux 应用程序来进行无线网络扫描,将结果放入一个结构中,然后以某种方式将其发送到另一个将使用数据的主应用程序。 我最初的想法是在主应用程序中创建一个管道,通过 execl 分叉并启动另一个可以写入管道的进程。像这样的:

pid_t pid = NULL;
int pipefd[2];
FILE* output;
char line[256];

pipe(pipefd);
pid = fork();
if (pid == 0)

// Child
  close(pipefd[0]);
  dup2(pipefd[1], STDOUT_FILENO);
  dup2(pipefd[1], STDERR_FILENO);
  execl("/sbin/wifiscan", "/sbin/wifiscan", (char*) NULL);


//Only parent gets here. Listen to what the wifi scan says
close(pipefd[1]);
output = fdopen(pipefd[0], "r");

while(fgets(line, sizeof(line), output))

//Here we can listen to what wifiscan sends to its standard output

但是,如果二进制 0 出现在输出中,这将不适用于二进制数据。因此,我可以将 wifiscan 应用程序的输出格式化为文本,将其发送到管道并在主应用程序中解析,或者以我还不知道的更智能的方式进行。

还有哪些其他方法可以在 Linux 中的进程之间可靠地交换数据?

【问题讨论】:

【参考方案1】:

我怀疑发生的事情是fgets() 正在正确读取 NUL 字符,但您将第一个字符解释为已读取行的末尾。这很棘手,因为fgets() 用于文本输入,它确实使用 '\0' 作为标记,而不是返回读取的字符数。即使您知道每一行都将被\n 终止,嵌入在一行中的原始二进制数据也有可能包含\n。所以,切换到fread(),这意味着二进制。您可以在每条消息的前面放置一个固定长度(例如 2 字节、4 字节)的消息大小,以便对方可以先读取该消息大小,然后使用 fread() 获取确切的消息大小,避免部分消息的混乱问题消息读取。

如果你真的想要让它保持一些奇怪的文本和二进制混合,你可以尝试在fgets() 之后使用ftell() 来找出你在流中还有多远,因此您的缓冲区中应该有多少个字符,但我从未见过一个严肃的系统会做如此骇人听闻的事情。

为了记录,没有做一些明显低效的事情,比如对二进制数据中的每个字符进行十六进制编码,你可以只对麻烦的字符进行编码。例如,可以使用 C 字符串文字转义序列,\0 表示 NUL,\\ 表示单个 \。虽然视觉检查不太容易,但使用八进制 \NNN 以编程方式对不可打印字符进行编码/解码可能更容易。如果有很多不可打印的字符,那么 base-64 uuencode 方法(例如在 MIME 电子邮件附件中使用)是另一种合适但完全不可读的编码。

【讨论】:

无论如何,ftell() 不太可能在管道等不可搜索的流上工作。 我同意为您的数据构建一个基本协议,然后使用fread() 而不是fgets()。这个answer 对FIFOs implementation 的问题可能会有额外的用途,因为它提供了几个关于如何构建这样一个协议的示例。【参考方案2】:

有很多..

我会读史蒂文斯。

http://www.kohala.com/start/unpv22e/unpv22e.html

【讨论】:

【参考方案3】:

通常人们会使用freadfwrite 来跨进程交换二进制结构。它适用于固定长度的记录,并且发送空值等没有问题。

在我漫长的职业生涯中,我发现在大多数应用程序中,交换易于解析的 ascii 字符串(例如,scanf)要比二进制数据好得多。这样可以观察和记录消息,并且可以通过远程登录和键入(通常是粘贴)来测试各个进程。程序员只要能读懂消息流量就更容易开发了。

【讨论】:

【参考方案4】:

可靠地交换数据?这让我想到了 0MQ (ZeroMQ) 库:http://zeromq.org

看看,作为奖励,您的进程甚至可以在远程计算机上交谈。

欢迎来到云端。

【讨论】:

以上是关于如何在 Linux 中的进程之间交换二进制数据的主要内容,如果未能解决你的问题,请参考以下文章

popen 在进程之间传递二进制数据

在 C 语言中使用 POSIX 在多个进程(不是线程,仅进程)之间共享二进制信号量

LINUX系统中进程如何管理控制

Linux 中 Python 父进程和 C 子进程之间的通信

二进制数组ArrayBuffer

在 Python 进程之间共享一个大的(只读)二进制字符串? [复制]