无法添加组播组

时间:2016-07-14 14:16:36

标签: erlang udp ipv6 multicast

尝试为ipv6添加组播组,但它返回错误。不明白这个问题。与ipv4一起工作正常

(test_client@127.0.0.1)1> {ok, S} = gen_udp:open(3333, [binary, {active, false}, {ip, {65342,0,0,0,0,0,34048,9029}}, inet6, {multicast_loop, false}]).
{ok,#Port<0.1587>}

(test_client@127.0.0.1)4> inet:setopts(S, [{add_membership, {{65342,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0}}}]).
{error,einval}

遗憾的是,erlang文档中的这个主题记录严重

也试过像ff3c:,ff32:

这样的地址

更新 我查看了Erlang / OTP 18.2源代码,有使用函数prim_inet:is_sockopt_val(add_membership, {{65280,0,0,0,0,0,34048,9029}, {0,0,0,0,0,0,0,0}})

并且它总是返回false,因为在prim_inet:type_value_2 / 2中我们有类型ip,值{_,_,_,_,_,_,_,_}并且它只等待ipv4 {_,_,_,_}。 一方面我知道为什么在打开套接字时不能用ipv6添加成员资格,但另一方面该做什么就是打开问题

1 个答案:

答案 0 :(得分:1)

它看起来不像Erlang的驱动程序已实现IPV6_ADD_MEMBERSHIP,但它确实有原始支持,因此您可以自己构建它。这种方法的一个问题是你很难对通常在头文件中定义的东西进行编码,因此你的解决方案不会非常便携。

-module(unssmraw).
-export([test/0]).


test() ->
  Port = 57100,
  Mad = <<65340:16,0:16,0:16,0:16,0:16,0:16,34048:16,9029:16>>,
  Ifindx = <<3:64>>,
  Ip6 = 41,
  Ip6am = 20,

  {ok, Sock} = gen_udp:open(Port, [{reuseaddr,true}, inet6, binary]),
  R3 = inet:setopts(Sock, [{raw, Ip6, Ip6am, <<Mad/binary, Ifindx/binary>> }]),
  io:format("ssm ok? ~w ~n", [R3]),
  receive
    {udp, S, A, Pr, Pk} -> io:format("watcher sees: Socket ~p Address ~p Port ~p Packet ~p ~n", [S, A, Pr, Pk]) end.

测试发件人示例:

echo hi | socat - UDP6-SENDTO:\"ff3c::8500:2345\":57100

示例运行:

$ erl
Erlang/OTP 19 [erts-8.0.1] [source-761e467] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V8.0.1  (abort with ^G)
1> unssmraw:test().
ssm ok? ok 
watcher sees: Socket #Port<0.453> Address {65152,0,0,0,47734,16383,65066,
                                           19977} Port 43511 Packet <<"hi\n">>  
ok

关于我的硬编码值的说明

  • 如何找到我在Ifindx中使用的接口索引被描述为here并且是64位的,因为这是我系统上int的大小而且是in in in in in in in in in in in .H)。
  • Ip6的值来自in.h
  • Ip6am是来自in6.h的IPV6_ADD_MEMBERSHIP。