今天看了霸爷的[url=http://blog.yufeng.info/archives/36]节点间通讯的通道微调[/url]和[url=http://blog.yufeng.info/archives/2659]谁引起busy_dist_port[/url]之后,自己将两章的内容连起来,组合成一个小程序,通过节点名查到相应的port,然后通过port查到相应的节点名,代码如下:
查看效果的时候,先启动两个erlang shell,
然后通过net_adm:ping(yansha).将两个节点联通起来。
之后再起一个节点$erl -sname yueping
这样就实现了一个查询和反查询。相关代码见附件
-module(busyPort).
-compile([export_all]).
start(Node) ->
Port = node_port(Node),
annotate_port(busy_dist_port, Port, get_node_map()).
node_port(Node)->
{_, Owner}=lists:keyfind(owner, 1, element(2, net_kernel:node_info(Node))),
hd([P|| P<-erlang:ports(), erlang:port_info(P, connected) == {connected,Owner}]).
get_node_map() ->
%% We're already peeking inside of the priave #net_address record
%% in kernel/src/net_address.hrl, but it's exposed via
%% net_kernel:nodes_info/0. Alas, net_kernel:nodes_info/0 has
%% a but in R14B* and R15B, so we can't use ... so we'll cheat.
%% e.g.
%% (foo@sbb)11> ets:tab2list(sys_dist).
%% [{connection,bar@sbb,up,<0.56.0>,undefined,
%% {net_address,{{10,1,1,34},57368},"sbb",tcp,inet},
%% [],normal}]
try
[begin
%% element(6, T) should be a #net_address record
%% element(2, #net_address) is an {IpAddr, Port} tuple.
if element(1, T) == connection,
size(element(2, element(6, T))) == 2 ->
{element(2, element(6, T)), element(2, T)};
true ->
{bummer, bummer}
end
end || T <- ets:tab2list(sys_dist)]
catch _X:_Y ->
%%error_logger:error_msg("~s:get_node_map: ~p ~p @ ~p\n",
%% [?MODULE, _X, _Y, erlang:get_stacktrace()]),
[]
end.
annotate_port(PortType, Port, NodeMap) ->
try
%% Need 'try': may race with disconnecting TCP peer
{ok, Peer} = inet:peername(Port),
case PortType of
busy_port ->
{busy_port, Peer};
busy_dist_port ->
{busy_dist_port, proplists:get_value(Peer, NodeMap, unknown)}
end
catch
_X:_Y ->
Port
end.
查看效果的时候,先启动两个erlang shell,
$ erl -sname liufan
$ erl -sname yansha
然后通过net_adm:ping(yansha).将两个节点联通起来。
之后再起一个节点$erl -sname yueping
[liufan@liufan busy_dist_port]$ erl -sname yueping
Erlang R16B01 (erts-5.10.2) [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V5.10.2 (abort with ^G)
(yueping@liufan)1> net_kernel:connect(liufan@liufan).
true
(yueping@liufan)2> busyPort:start(liufan@liufan).
{busy_dist_port,liufan@liufan}
(yueping@liufan)3> net_kernel:nodes_info().
{ok,[{liufan@liufan,[{owner,<0.40.0>},
{state,up},
{address,{net_address,{{127,0,0,1},45314},
"liufan",tcp,inet}},
{type,normal},
{in,11},
{out,13}]},
{yansha@liufan,[{owner,<0.47.0>},
{state,up},
{address,{net_address,{{127,0,0,1},39923},
"liufan",tcp,inet}},
{type,normal},
{in,5},
{out,4}]}]}
(yueping@liufan)4>
这样就实现了一个查询和反查询。相关代码见附件