如何通过ID获取Erlang端口?

时间:2016-01-09 14:25:58

标签: erlang erlang-ports

当我有一个Erlang进程ID,使用pid/3list_to_pid/1函数(内部做同样的事情)时,我可以进行调试的过程。

Process = pid(0,4,1).
Process = list_to_pid("<0.4.1>").

所以问题是;怎么样ports

有许多函数接口可以接受process()port()数据类型,例如register/2。所以我需要知道是否有办法通过他们的ID(例如#Port<0.567>)来处理端口。是禁止的吗?如果是的话,有什么理由吗?

2 个答案:

答案 0 :(得分:4)

我并不知道标准库中有任何内容可以帮助解决这个问题,但the recon_lib:term_to_port/1 function中有recon library可以执行您想要的操作。例如:

1> {ok,L} = gen_tcp:listen(0, []).
{ok,#Port<0.687>}
2> L = recon_lib:term_to_port("#Port<0.687>").
#Port<0.687>

此代码在临时端口上打开侦听套接字并将其存储在变量L中。然后,它使用模式匹配断言,将字符串化端口#Port<0.687>传递给recon_lib:term_to_port/1的结果返回与L完全相同的套接字。

答案 1 :(得分:2)

首先,让我们尽早建立,你需要了解为什么你认为你需要这个功能。也许你有充分的理由 - 但这对我来说有点像X-Y问题。

[编辑:我刚刚看到史蒂夫的帖子使用了重建库。如果你碰巧正在使用侦察,这是一个很棒的方式来做到这一点。如果不是......去了解侦察。这很棒。下面的解决方案是你从头开始做事。]

那就是说,让我们看看我们能做些什么,因为我们只有erlang:port_to_list/1可以使用(我知道)。

考虑类似的事情:

-module(porter).
-export([port/2]).

-spec port(non_neg_integer(), non_neg_integer()) -> undefined | port().
port(A, B) ->
    PortString = lists:flatten(io_lib:format("#Port<~w.~w>", [A, B])),
    CheckPort = fun(Z) -> PortString == erlang:port_to_list(Z) end,
    case lists:filter(CheckPort, erlang:ports()) of
        []  -> undefined;
        [P] -> P
    end.

在shell中:

1> c(porter).
{ok,porter}
2> erlang:ports().
[#Port<0.0>,#Port<0.318>,#Port<0.328>,#Port<0.337>]
3> porter:port(0, 328).
#Port<0.328>
4> porter:port(0, 400).
undefined

这可能会也可能不会达到您的目的......但请再次考虑为什么需要这样做。在项目中添加实用程序功能可能会更加明智,如果需要手动操作,可以跟踪实际打开的端口。