2016-07-14 72 views
3

尝试为ipv6添加多播组,但它返回错误。不明白问题。在IPv4中它工作正常不能添加多播组

([email protected])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>} 

([email protected])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 addrreses:,FF32:

UPDATE 我已经研究过二郎山/ 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的成员资格,但另一方面要做的事情是打开的问题

+0

在第三个数字中,'3'意思是'Realm Local',它尚未定义,等待RFC定义它;你可能想用'2'作为'Admin local'。此外,在第四位数字中,高位必须为'0'(不能大于等于8),并且如果设置了R位,则必须设置“P”位,如果“P '位被置位,必须设置'T'位(数字必须为0,1,3或7)。设置'R'位表示您正在嵌入RP地址。可能的话,你只需要设置'T'位(第四位是'1')来表示一个暂时的,而非永久的,众所周知的地址。这意味着使用'ff21'。 –

+0

@RonMaupin谢谢你的答案:) 我会解决它。但第二个问题是,otp只期望ipv4 addr –

+0

IPv6和IPv4是两个完全独立的第三层协议。任何期望IPv4地址的东西都需要IPv4地址,而不是IPv6地址。我不知道你在用什么,但你必须有一个IPv6网络,包括IPv6多播客户端和源代码。 –

回答

2

它看起来不像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的大小,它是在MREQ在我in6.h.一个int)
  • Ip6的值是从in.h中
  • Ip6am是从IPV6_ADD_MEMBERSHIP in6.h.
+0

谢谢!这就是我正在寻找的东西 –