如何从erlang读/写到命名管道?

Posted

技术标签:

【中文标题】如何从erlang读/写到命名管道?【英文标题】:How to read/write from erlang to a named pipe? 【发布时间】:2010-04-14 14:04:42 【问题描述】:

我需要我的 erlang 应用程序通过命名管道进行读写。

将命名管道作为文件打开将失败并显示eisdir

我编写了以下模块,但它很脆弱,并且在很多方面都感觉不对。一段时间后它也无法阅读。有没有办法让它更...优雅?

-module(port_forwarder).
-export([start/2, forwarder/2]).

-include("logger.hrl").

start(From, To)->
    spawn(fun() -> forwarder(From, To) end).

forwarder(FromFile, ToFile) ->
  To = open_port(spawn,"/bin/cat > " ++ ToFifo, 
                   [binary, out, eof,packet, 4]),
  From = open_port(spawn,"/bin/cat  " ++ FromFifo, 
                   [binary, in, eof, packet, 4]),
  forwarder(From, To, nil).

forwarder(From, To, Pid) ->
  receive
    Manager, command, Bin ->
      ?ERROR("Sending : ~p", [Bin]),
      To ! self(), command, Bin,
      forwarder(From, To, Manager);
    From ,data,Data ->
      Pid ! self(), data, Data,
      forwarder(From, To, Pid);
    E -> 
      ?ERROR("Quitting, first message not understood : ~p", [E])
  end.

您可能已经注意到,它在接受或返回的内容中模仿了端口格式。 我希望它替换将读取管道另一端并从调试器启动的 C 代码。

【问题讨论】:

【参考方案1】:

假设您在 Unix 上运行,我认为 eisdir 失败来自此代码。

https://github.com/erlang/otp/blob/master/erts/emulator/drivers/unix/unix_efile.c

efile_openfileefile_may_openfile。他们都做检查假设如果一个文件是!IS_REG(f) 那么它是一个目录。这似乎有缺陷,但也许有充分的理由不打开非常规文件。 /dev/null 的组合也很有趣。

我之前也遇到过这个问题。也许是时候抓挠痒痒了。

【讨论】:

【参考方案2】:

我刚刚遇到了这个问题。万一以后别人发现这个线程,Erlang不支持打开命名管道的原因和设备文件打不开的原因是一样的。此链接总结了基本原理:

http://www.erlang.org/faq/problems.html#id56464

【讨论】:

Erlang 确实支持打开命名管道,但不支持将它们作为文件打开。这是您的回复中遗漏的一个非常重要的区别。

以上是关于如何从erlang读/写到命名管道?的主要内容,如果未能解决你的问题,请参考以下文章

写和读命名管道

Java中命名管道的并发读/写(在Windows上)

linux进程间通信:匿名管道&&命名管道

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

shell 命名管道,进程间通信, ncat作http server

如何继续从命名管道/流中发送/读取消息