2

当我有一个 Erlang 进程 ID、使用pid/3list_to_pid/1函数(在内部做同样的事情)时,我可以获取该进程以用于调试目的。

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

所以问题是;端口呢?

有很多函数接口可以同时接受process()数据port()类型,比如register/2. 所以我需要知道是否有办法通过他们的ID(例如#Port<0.567>)来获取端口,比如进程。是否被禁止?如果是这样,有什么理由吗?

4

2 回答 2

5

我不知道标准库中有什么可以帮助解决这个问题,但是侦察库recon_lib:term_to_port/1函数可以满足您的需求。例如:

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/1L.

于 2016-01-09T15:01:47.150 回答
2

首先,让我们尽早建立这一点,您需要了解您认为需要此功能的原因。也许你有充分的理由——但这对我来说很像 XY 问题。

[编辑:我刚刚看到史蒂夫的帖子为此使用了侦察库。如果您碰巧正在使用侦察,那是一种很棒的方法。如果没有...去了解侦察。它非常好。下面的解决方案是如果你从头开始做事。]

也就是说,让我们看看我们能做什么,因为我们只需要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.

在外壳中:

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

这可能会或可能不会达到您的目的......但再次考虑一下您为什么需要它。如果您需要手动操作它们,那么在您的项目中添加一个实用程序函数来跟踪您实际打开的端口可能会更加明智。

于 2016-01-09T15:08:57.543 回答