erlang - 如何在 Erlang 中发送多播消息并重用端口?

标签 erlang multicast bonjour zeroconf

我的程序有了一个良好的开端,这是我的第一个真正的 Erlang 程序。 我让它监听消息、读取消息并解析它们。我也把它寄给他们了。 困扰我的一件小事是我无法在端口 5353 上发送,我已经尝试了所有方法。 我机器上的所有其他应用程序都可以在端口 5353、SubEthaEdit、iTunes、iChat 上监听和发送。

解决方案必须在端口 5353 上广播发送,原因如下。

"如果收到的多播 DNS 查询中的源 UDP 端口不是端口 5353,这表明发起查询的客户端是 没有完全实现所有组播 DNS 的简单客户端。 在这种情况下,多播 DNS 响应者必须发送 UDP 响应 通过单播直接返回到客户端,到查询数据包的 源IP地址和端口。这个单播响应必须是 传统的单播响应将由传统的 单播 DNS 服务器;例如,它必须重复查询 ID 和 查询包中给出的问题。 “

发送组播消息时均报告端口:5353。 我真的希望我的应用程序运行良好并做同样的事情,在端口 5353 上发送。 这是我现在的模块。

-module(zeroconf).

-include("zeroconf.hrl").

-export([open/0,start/0]).
-export([stop/1,receiver/0]).
-export([send/1]).

-define(ADDR, {224,0,0,251}).
-define(PORT, 5353).

send(Domain) ->
    {ok,S} = gen_udp:open(0,[{broadcast,true}]), % I really want this Port to be 5353 :-(
    % this doesn't complain or throw errors but it also doesn't work :-(        
    %{ok,S} = gen_udp:open(?PORT,[{reuseaddr,true}, {ip,?ADDR}, {broadcast,true},multicast_ttl,4}, {multicast_loop,false}, binary]),
    P = #dns_rec{header=#dns_header{},qdlist=[#dns_query{domain=Domain,type=ptr,class=in}]},
    gen_udp:send(S,?ADDR,?PORT,inet_dns:encode(P)),
    gen_udp:close(S).

以下是一些输出的样子。

这是来自 SubEthaEdit 的查询,用于查找本地网络上的其他实例,请注意它显示端口:5353

From: {192,168,0,105}
Port: 5353
Data: {ok,{dns_rec,{dns_header,0,true,'query',true,false,false,false,false,0},
                   [],
                   [{dns_rr,"_see._tcp.local",ptr,in,0,0,
                            "jhr@Blackintosh._see._tcp.local",undefined,[],
                            false}],
                   [],[]}}

现在这是我的模块中的一个查询,用于查找本地网络上的 iTunes 实例,请注意它显示端口:59795 按照现在的代码,该端口是随机的。我真的希望它是 5353。

From: {192,168,0,105}
Port: 59795
Data: {ok,{dns_rec,{dns_header,0,false,'query',false,false,false,false,false,
                               0},
                   [{dns_query,"_daap._tcp.local",ptr,in}],
                   [],[],[]}}

有人对 UDP 多播有任何神秘的见解吗?更新以便我可以尝试并接受答案。我想我就是做不到。

最佳答案

更新:好的,我已经找到了我认为可行的解决方案。关键点似乎与加入多播组有关。

{ok, Socket} = gen_udp:open(Port=5353, [binary, {active, false}, {reuseaddr, true},
                                        {ip, Addr}, {add_membership, {Addr, IAddr}}]).
  1. 地址:多播组(例如 {224, 0, 0, 251}
  2. IAddr 是本地 IP 接口(interface)(例如可以使用默认的 {0,0,0,0})

(当然,请确保您没有运行可能会发生冲突的 DNS 守护程序)

关于erlang - 如何在 Erlang 中发送多播消息并重用端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1746257/

相关文章:

erlang - erlang-ls 是否支持变量的定义?

iphone - 我可以在后台通过蓝牙发现其他 iOS 设备吗?

ios - 无法通过 wifi 查看事件服务器并使用 Bonjour 和 NSNetServiceBrowserDelegate 一直连接它?

c++ - avahi:广播我的服务有更新信息

mysql - 从mysql迁移到Couchbase。这是个好主意吗?

Erlang eDoc : Function doc comments don't show up in output

docker - 如何在 Docker 中支持多播网络

python - 在 Python 和 Qt 之间共享多播接收器端口

tcp - 我可以为 TCP 使用广播或多播吗?

erlang - 在 Erlang 中,是否可以将正在运行的进程发送到不同的节点?