无法添加组播组 [英] can't add multicast group

查看:360
本文介绍了无法添加组播组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

 (test_client@127.0.0.1)1> {ok,S} = gen_udp:open(3333,[binary,{active,false},{ip,{65342,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}}}]) 。
{error,einval}

不幸的是,这个主题在erlang docs被记录在案>

也尝试过像ff3c这样的addrreses:ff32:



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



,它总是返回false,因为在prim_inet中:type_value_2 / 2我们输入ip,值 {_,_,_,_,_,_,_,_} ,它只等待ipv4 { _,_,_,_}
一方面我知道为什么不能在打开套接字时添加ipv6的成员资格,但另一方面要做的则是打开问题

解决方案

它看起来不像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 see: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(中止与^ G)
1> ; unssmraw:测试()。
ssm好吗? ok
观察者看到:Socket#Port< 0.453>地址{65152,0,0,47734,16383,65066,
19977}端口43511 Packet<hi\\\
>>
ok



关于我硬编码值的注释




  • 如何找到我在中使用的界面索引Ifindx 被描述这里,是64位,因为这是我的系统上的int的大小,这是我的in6.h中的mreq中的一个int。)

  • Ip6 的值来自in.h

  • Ip6am 是in6.h中的IPV6_ADD_MEMBERSHIP。


Trying to add multicast group for ipv6, but it returns error. don't understand the problem. with ipv4 it works fine

(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}

unfortunately this topic in erlang docs is badly documented

also have tried with addrreses like ff3c: , ff32:

UPDATE i've looked into Erlang/OTP 18.2 source code, there is using function prim_inet:is_sockopt_val(add_membership, {{65280,0,0,0,0,0,34048,9029}, {0,0,0,0,0,0,0,0}})

and it always return false, because in prim_inet:type_value_2/2 we have type ip, value {_,_,_,_,_,_,_,_} and it waits only for ipv4 {_,_,_,_}. on the one hand i know why can't add membership with ipv6 when open socket, but on other hand what to do is opened question

解决方案

It doesn't look like Erlang's driver has implemented IPV6_ADD_MEMBERSHIP, but it does have raw support so you could construct it yourself. A problem with this approach is that you are hard coding things usually defined in header files, so your solution wont be very portable.

-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.

Example test sender:

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

Example run:

$ 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

Notes on my hardcoded values

  • How to find the interface index I use in Ifindx is described here and is 64-bit since that is the size of an int on my system and it is an int in mreq in my in6.h.)
  • Ip6's value is from in.h
  • Ip6am is IPV6_ADD_MEMBERSHIP from in6.h.

这篇关于无法添加组播组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆