Получение данных по udp

882 views
Skip to first unread message

Анастасия Субботина

unread,
Feb 17, 2014, 12:45:13 AM2/17/14
to erlang-...@googlegroups.com
Я настраиваю получение данных по udp, написала код для проверки самого факта получения

-module(udp_bin).
-compile([export_all]).

start([Host,Port]) ->
{ok,IpAddress} = inet_parse:address(Host),
{ok,Socket} = gen_udp:open(erlang:list_to_integer(Port),
[

binary,
{active,true},
{reuseaddr,true}

]),
inet:setopts(Socket,[{add_membership,{IpAddress,{0,0,0,0}}}]),
io:format("Socket ~p:~n", [Socket]),
Pid = spawn(fun() -> loop(Socket) end), %%15
ok = gen_udp:controlling_process(Socket,Pid).


loop(Socket) ->
receive
{udp,_Socket,_SrcAddr,_Port,Bin} ->
io:format("Bin ~p:~n", [Bin]), %%25
loop(Socket)

набираю следующие команды

1> A = ["239.192.7.27","24027"].
["239.192.7.27","24027"]
4> udp_bin:start(A).
Socket #Port<0.2400>:
ok

что изменить что бы начать получать данные?

Andy

unread,
Feb 17, 2014, 1:24:03 AM2/17/14
to erlang-...@googlegroups.com


понедельник, 17 февраля 2014 г., 7:45:13 UTC+2 пользователь Анастасия Субботина написал:
1> A = ["239.192.7.27","24027"].
["239.192.7.27","24027"]
4> udp_bin:start(A).
Socket #Port<0.2400>:
ok

что изменить что бы начать получать данные?

Передать их через netcat,  например?
А вообще, если Ваш код намеревается жить чуть больше, нежели сдача зачета, то переделайте под OTP. Здесь необходимость этого неоднократно обсуждалась.

Игнат Толчанов

unread,
Feb 17, 2014, 2:38:05 AM2/17/14
to erlang-...@googlegroups.com
Чтобы получить данные, надо бы их вообще откуда-нибудь передать.
Это можно сделать прямо из консоли:

1> {ok, Srv} = gen_udp:open(2222, [{active,true},binary]).
{ok,#Port<0.584>}
2> {ok, Cl} = gen_udp:open(3333). 
{ok,#Port<0.595>}
3> flush().
ok
4> gen_udp:send(Cl, {127,0,0,1}, 2222, <<"foobar">>).
ok
5> flush().                                          
Shell got {udp,#Port<0.584>,{127,0,0,1},3333,<<"foobar">>}
ok


понедельник, 17 февраля 2014 г., 9:45:13 UTC+4 пользователь Анастасия Субботина написал:

Анастасия Субботина

unread,
Feb 17, 2014, 2:46:19 AM2/17/14
to erlang-...@googlegroups.com
я их получаю от сюда 1> A = ["239.192.7.27","24027"].

понедельник, 17 февраля 2014 г., 14:38:05 UTC+7 пользователь Игнат Толчанов написал:

Dmitry Belyaev

unread,
Feb 17, 2014, 2:59:50 AM2/17/14
to erlang-...@googlegroups.com, Анастасия Субботина
Чтобы в первом и отсюда в последнем сообщении пишутся слитно.

Для того, чтобы откуда-то что-то получать по udp, надо чтобы удаленный хост знал, куда посылать. Для этого его надо настроить или отправить ему какую-то специальную команду.
--
Best wishes,
Dmitry Belyaev

Игнат Толчанов

unread,
Feb 17, 2014, 3:04:46 AM2/17/14
to erlang-...@googlegroups.com
А они оттуда уходят? Кто их шлет? Он работает?

понедельник, 17 февраля 2014 г., 11:46:19 UTC+4 пользователь Анастасия Субботина написал:

Игнат Толчанов

unread,
Feb 17, 2014, 3:10:11 AM2/17/14
to erlang-...@googlegroups.com, Анастасия Субботина
Там же мультикаст. Насколько я понял по коду, предполагается, что удаленный хост шлет данные в мультикаст группу.

понедельник, 17 февраля 2014 г., 11:59:50 UTC+4 пользователь Dmitry Belyaev написал:

Анастасия Субботина

unread,
Feb 17, 2014, 3:12:01 AM2/17/14
to erlang-...@googlegroups.com, Анастасия Субботина
Куда посылать они знают, другое дело что надо отправить специальную команду.

понедельник, 17 февраля 2014 г., 14:59:50 UTC+7 пользователь Dmitry Belyaev написал:

Анастасия Субботина

unread,
Feb 17, 2014, 3:14:37 AM2/17/14
to erlang-...@googlegroups.com, Анастасия Субботина
Правильно и переменная A как раз эта группа

понедельник, 17 февраля 2014 г., 15:10:11 UTC+7 пользователь Игнат Толчанов написал:

Игнат Толчанов

unread,
Feb 17, 2014, 3:32:10 AM2/17/14
to erlang-...@googlegroups.com
Слушайте, ваш код работает (за исключением того, что вы забыли, видимо, скопировать end. для receive).
Я предлагаю посмотреть на то, верно ли указана группа и порт и работает ли источник данных.


понедельник, 17 февраля 2014 г., 9:45:13 UTC+4 пользователь Анастасия Субботина написал:
Я настраиваю получение данных по udp, написала код для проверки самого факта получения

Анастасия Субботина

unread,
Feb 17, 2014, 3:46:44 AM2/17/14
to erlang-...@googlegroups.com
Да, действительно end. не скопировала, в оригинале это присутствует. Вопрос другого плана, вы пробовали его на компьютере с Windows или Linux-like операционкой?

понедельник, 17 февраля 2014 г., 15:32:10 UTC+7 пользователь Игнат Толчанов написал:

Игнат Толчанов

unread,
Feb 17, 2014, 4:04:52 AM2/17/14
to erlang-...@googlegroups.com
Ubuntu 12.04
Erlang R16B03 (erts-5.10.4), сборка от esl

понедельник, 17 февраля 2014 г., 12:46:44 UTC+4 пользователь Анастасия Субботина написал:

Анастасия Субботина

unread,
Feb 17, 2014, 4:17:24 AM2/17/14
to erlang-...@googlegroups.com
Спасибо.

понедельник, 17 февраля 2014 г., 16:04:52 UTC+7 пользователь Игнат Толчанов написал:

Анастасия Субботина

unread,
Feb 19, 2014, 8:11:33 AM2/19/14
to erlang-...@googlegroups.com
У кого-нибудь есть рабочий вариант multicast'а, проверенный, чтобы точно определить в чем проблема в связи или в коде?

понедельник, 17 февраля 2014 г., 16:04:52 UTC+7 пользователь Игнат Толчанов написал:

Игнат Толчанов

unread,
Feb 19, 2014, 8:43:19 AM2/19/14
to erlang-...@googlegroups.com
Ваш код правильный и работает как надо. Я уже об этом писал. Только что еще раз проверили
На одном компьютере запущен ваш код, на другом в консоли делаем:
1> {ok, S} = gen_udp:open(6660, [binary]).
{ok,#Port<0.584>}
2> gen_udp:send(S, {239,192,7,27}, 24027, <<"foobar123">>).
ok


среда, 19 февраля 2014 г., 17:11:33 UTC+4 пользователь Анастасия Субботина написал:

Анастасия Субботина

unread,
Feb 19, 2014, 9:55:23 AM2/19/14
to erlang-...@googlegroups.com
спасибо еще раз.

среда, 19 февраля 2014 г., 17:43:19 UTC+4 пользователь Игнат Толчанов написал:

Max Lapshin

unread,
Feb 19, 2014, 11:43:59 AM2/19/14
to erlang-...@googlegroups.com
А нет ли у вас проблем с igmp? Роутеры любят это не пропускать.

Анастасия Субботина

unread,
Feb 19, 2014, 9:52:59 PM2/19/14
to erlang-...@googlegroups.com
у меня напрямую, без роутера

среда, 19 февраля 2014 г., 20:43:59 UTC+4 пользователь Max Lapshin написал:

Max Lapshin

unread,
Feb 19, 2014, 11:54:35 PM2/19/14
to erlang-...@googlegroups.com
Тогда вам мультикаст должен обычным броадкастом сваливаться на карточку. Его можно увидеть в wireshark.

Если вы с того же компьютера рассылаете, то проверьте, что у посылающей стороны стоит multicast_loop. 


Анастасия Субботина

unread,
Feb 20, 2014, 12:14:18 AM2/20/14
to erlang-...@googlegroups.com
Я проверяю tcpdump, там активности нет. Идут данные и активность должна быть высокая.

четверг, 20 февраля 2014 г., 11:54:35 UTC+7 пользователь Max Lapshin написал:

Andy

unread,
Feb 21, 2014, 1:16:26 AM2/21/14
to erlang-...@googlegroups.com
На всякий случай уточню: у Вас компьютеры включены в свич или кроссовером? У меня роутер со стороны LAN (да, именно с одной стороны от НАТа) не пропускал мультикасты. То есть, в домашней сети они не ходили вообще. Потратил три дня на разные проверки. Обнаружил при прямом включении (кроссовером). Пришлось докупать самый простой свич - тогда заработало.

четверг, 20 февраля 2014 г., 4:52:59 UTC+2 пользователь Анастасия Субботина написал:

Анастасия Субботина

unread,
Feb 21, 2014, 5:25:26 AM2/21/14
to erlang-...@googlegroups.com
У меня один компьютер выходит в интернет, то есть чтобы не создавать дополнительных проблем я подключила его на прямую.

пятница, 21 февраля 2014 г., 13:16:26 UTC+7 пользователь Andy написал:

Анастасия Субботина

unread,
Feb 21, 2014, 5:29:34 AM2/21/14
to erlang-...@googlegroups.com
Может есть особенность, но для получения мультикаста создан vpn, для надежности канала и публикатор идентифицирует по статическому IP получателя.


пятница, 21 февраля 2014 г., 13:16:26 UTC+7 пользователь Andy написал:
На всякий случай уточню: у Вас компьютеры включены в свич или кроссовером? У меня роутер со стороны LAN (да, именно с одной стороны от НАТа) не пропускал мультикасты. То есть, в домашней сети они не ходили вообще. Потратил три дня на разные проверки. Обнаружил при прямом включении (кроссовером). Пришлось докупать самый простой свич - тогда заработало.

Max Lapshin

unread,
Feb 21, 2014, 6:00:42 AM2/21/14
to erlang-...@googlegroups.com
Анастасия, вы сейчас возитесь с проблемами сетевого уровня.  Пропихнуть по VPN _мультикаст_ может быть очень непросто.

Лучше всего взять второй компьютер и воткнуть их в свитч.

Andy

unread,
Feb 24, 2014, 1:18:40 AM2/24/14
to erlang-...@googlegroups.com
Присоединяюсь. Сделайте упрощенный вариант сначала.

пятница, 21 февраля 2014 г., 13:00:42 UTC+2 пользователь Max Lapshin написал:

Ivan Petrushin

unread,
Feb 28, 2014, 11:31:13 AM2/28/14
to erlang-...@googlegroups.com
Без специальных танцев с бубном multicast внутри VPN-соедиения не передать, эта технология де-факто работает на 2-м уровне (MAC-адресов) и предназначена исключительно для локальных сетей.
Я бы на Вашем месте взял два компа, соединенных через управляемый коммутатор (обычный коммутатор мультикаст превращает в броадкаст, как тут уже заметили).

пятница, 21 февраля 2014 г., 19:29:34 UTC+9 пользователь Анастасия Субботина написал:

Анастасия Субботина

unread,
Mar 1, 2014, 9:05:30 AM3/1/14
to erlang-...@googlegroups.com
Спасибо

пятница, 28 февраля 2014 г., 23:31:13 UTC+7 пользователь Ivan Petrushin написал:

Alexander Dergachev

unread,
Mar 1, 2014, 3:28:18 PM3/1/14
to erlang-...@googlegroups.com, erlang-...@googlegroups.com
все так активно советуют брать два компьютера, а я вот не понимаю, почему никто не предложит взять пару виртуальных машин? тот же виртуал бокс например. будет там и локальная сеть, и мультикаст, и все что душа пожелает. и не надо никакого дополнительного оборудования, ни каких проводов...


--
Вы получили это сообщение, поскольку подписаны на группу Erlang по-русски.
 
Чтобы отказаться от подписки на эту группу и перестать получать из нее сообщения, отправьте электронное письмо на адрес erlang-russia...@googlegroups.com.
Чтобы добавлять сообщения в эту группу, отправьте письмо по адресу erlang-...@googlegroups.com.
Настройки подписки и доставки писем: https://groups.google.com/groups/opt_out.

Max Lapshin

unread,
Mar 1, 2014, 3:37:47 PM3/1/14
to erlang-...@googlegroups.com
Потому что даже два компьютера — это всё равно немного не то.

Мультикаст — это очень паршивая, капризная и хрупкая штука. Послать IGMP в правильный интерфейс и продолжать туда посылать не так то просто, когда у тебя два сетевых интерфейса.


Анастасия так и не рассказала, зачем ей вообще понадобился мультикаст и есть ли какие-то ещё проблемы сейчас. Обычно он бывает нужен либо:

1) для WS discovery, что маловероятно, кому нужен эрланг не на сервере
2) для видеостриминга, что так же маловероятно
3) для получения биржевых данных, что вполне может быть, но там надо изучать технические условия подключения
4) для каких-то служебных штук типа мультикастовой рассылки обновления прошивки (см видеостриминг)

Я сходу не могу себе представить, для чего ещё он может понадобиться. И во всех этих случаях я бы не стал полагаться на виртуалки: если мультикаст пошел между ними, ещё не значит, что он пойдет в продакшне. Достаточно на роутере неправильно настроить PIM и всё.

Но к слову сказать на локалхосте с multicast_loop,true проблем то быть не должно.

этот код без особых проблем забирает мультикаст в _простых_ условиях.


Timofey root

unread,
Mar 2, 2014, 8:26:56 AM3/2/14
to erlang-...@googlegroups.com
Например есть плавающий ресурс, который может перемещаться между серверами (например виртуальная машина, сохраняя при этом MAC, IP и т.п.). На каждом сервере установлена служба, которая знает какие ресурсы прямо сейчас работают на этом сервере.

Теперь серверу резервного копирования нужно сделать копию виртуальной машины снаружи - для этого нужно узнать где она сейчас работает.

Сервер резервных копий отправляет мультикаст: “Эй, у кого виртуалка 123”? И тот у кого она есть отвечает.

Я тоже думаю такую систему у себя сделать в будущем, но с мультикастом пока ни разу не сталкивался - только в теории адресации IPv6 читал и для такой задачи он как раз подходит.

Ivan Petrushin

unread,
Mar 2, 2014, 10:24:43 AM3/2/14
to erlang-...@googlegroups.com
Для такой задачи имхо мультикаст не нужен. Посылайте щироковещательный запрос, в ответ полУчите адрес узла, на котором нужная вам вирт. машина, дальше можно общаться юникастом.

воскресенье, 2 марта 2014 г., 22:26:56 UTC+9 пользователь Timofey root написал:

Ivan Petrushin

unread,
Mar 2, 2014, 10:29:06 AM3/2/14
to erlang-...@googlegroups.com
По поводу капризности - соглашусь. Причем тут еще важно, на каком оборудовании сеть построена, у D-Link своя логика, у Cisco - другая. Мы почти месяц пытались разрулить мультикаст трафик между двумя сетями (запрос одного из клиентов об отписке от определенной группы вещания передавался на все коммутаторы сети) , пока PIM посередине не поставили, проблемы не прекратились.

воскресенье, 2 марта 2014 г., 5:37:47 UTC+9 пользователь Max Lapshin написал:

Andy

unread,
Mar 3, 2014, 1:16:35 AM3/3/14
to erlang-...@googlegroups.com
В продакшне мультикаст используется, например, для многоточечной раздачи аудио. Передача множества аудиопотоков на еще большее множество аудиоустройств при помощи мультикаста решает вопрос сохранения пропускной способности канала, в том числе и за счет полного неиспользования полосы каналами, на которые в данный момент нет подписчиков. Я работал именно в таком направлении. И согласен с Максимом, что две виртуалки - вовсе не есть два физических устройства. "Не экономьте на детях"

суббота, 1 марта 2014 г., 22:37:47 UTC+2 пользователь Max Lapshin написал:

Анастасия Субботина

unread,
Mar 3, 2014, 5:06:20 PM3/3/14
to erlang-...@googlegroups.com
Это необходимо для получения биржевых данных ftp://ftp.moex.com/pub/FAST/Spectra/templates/configuration.xml но для организации подключения через интнет в целях тестирования это все пускают через vpn для контроля подписчиков. Вот это мне и нужно организовать.

Max Lapshin

unread,
Mar 3, 2014, 5:09:55 PM3/3/14
to erlang-...@googlegroups.com
Вам через vpn раздают мультикаст или по vpn пускают до сервера, где вы можете FAST получать?

Анастасия Субботина

unread,
Mar 5, 2014, 6:27:04 AM3/5/14
to erlang-...@googlegroups.com
Раздают.

вторник, 4 марта 2014 г., 5:09:55 UTC+7 пользователь Max Lapshin написал:

Анастасия Субботина

unread,
Jul 14, 2014, 8:51:41 AM7/14/14
to erlang-...@googlegroups.com
У кого есть опыт работы с мультикастом, а именно с igmp v3 и соответственно с ssm (source specific multicast), что нужно добавить или изменить в коде представленом в заглавии?

Max Lapshin

unread,
Jul 14, 2014, 12:47:33 PM7/14/14
to erlang-...@googlegroups.com
Options = [binary,{reuseaddr,true},{active,once},{recbuf,2*1024*1024},inet,{ip,Addr},{multicast_ttl,4},{multicast_loop,true},{add_membership,{Addr,GwIP}}],
gen_udp:open(Port, Options)

Тут особо ничего и не добавить.

Что именно вы хотите сделать?



2014-07-14 14:51 GMT+02:00 Анастасия Субботина <spasen...@gmail.com>:
У кого есть опыт работы с мультикастом, а именно с igmp v3 и соответственно с ssm (source specific multicast), что нужно добавить или изменить в коде представленом в заглавии?

--
Вы получили это сообщение, поскольку подписаны на группу "Erlang по-русски".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес erlang-russia...@googlegroups.com.
Чтобы отправлять сообщения в эту группу, отправьте письмо на электронный адрес erlang-...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.

Анастасия Субботина

unread,
Jul 14, 2014, 1:07:03 PM7/14/14
to erlang-...@googlegroups.com
Я хочу получать данные, код, в том виде котором он сейчас есть самостоятельно подписаться на данные не может. Если сперва запустить vlc, а потом его(код), то все работает, но это не нормально, хотелось бы самостоятельно подписываться.

Max Lapshin

unread,
Jul 15, 2014, 3:08:36 AM7/15/14
to erlang-...@googlegroups.com
Анастасия, мы неминуемо упремся в то, что вам надо показать код.

Анастасия Субботина

unread,
Jul 15, 2014, 4:46:13 AM7/15/14
to erlang-...@googlegroups.com
Я могу еще раз показать, там ничего не изменилось


-module(udp_bin).
-compile([export_all]).
 
start([Host,Port]) ->
    {ok,IpAddress} = inet:parse_address(Host),
    {ok,Socket} = gen_udp:open(erlang:list_to_integer(Port),
        [
            inet,
            binary,
            {active,true},
            {reuseaddr,true},
            {multicast_ttl, 30},
            {add_membership,{IpAddress,{0,0,0,0}}}
        ]),
    io:format("Socket ~p:~n", [Socket]),
    Pid = spawn(fun() -> loop(Socket) end),
    io:format("Pid :~p~n",[Pid]),            %%15
    ok = gen_udp:controlling_process(Socket,Pid).
 
 
loop(Socket) ->
    receive
        {udp,_Socket,_SrcAddr,_Port,Bin} ->
            io:format("Bin ~p:~n", [Bin]),           %%25
            loop(Socket);
        Msg ->
            io:format("Msg ~p:~n", [Msg])
    end.


Анастасия Субботина

unread,
Jul 15, 2014, 5:05:10 AM7/15/14
to erlang-...@googlegroups.com
если я просто запускаю код, то подписки нет и нет данных для обработки

 s5@s5:~$ erl
Erlang/OTP 17 [erts-6.1] [source] [64-bit] [smp:8:8] [async-threads:10] [kernel-poll:false]

Eshell V6.1  (abort with ^G)
1> A = ["239.192.7.27","24027"].
["239.192.7.27","24027"]
2> udp_bin:start(A).
Socket #Port<0.495>:
Pid :<0.36.0>
ok
3>

если я сперва запускаю vlc

s5@s5:~$ cvlc udp://172.27...@239.192.7.27:24027
VLC media player 2.1.4 Rincewind (revision 2.1.4-0-g2a072be)
[0x16b9b58] dummy interface: using the dummy interface module...

а затем той же командой код, то получаю следующее

Eshell V6.1  (abort with ^G)
1> A = ["239.192.7.27","24027"].
["239.192.7.27","24027"]
2> udp_bin:start(A).
Socket #Port<0.495>:
Pid :<0.36.0>
ok
Bin <<192,248,224,208,4,101,180,35,99,59,122,65,97,11,188,129,140,246,32,7,26,
      199,35,254,88,225,128,128,128,128,5,180,128,40,125,7,219,0,216,128,128,
      128,128>>:
Bin <<192,248,224,208,4,101,181,35,99,59,122,65,97,11,235,130,140,247,30,112,
      70,199,35,254,3,39,131,128,128,128,128,29,233,128,40,125,7,232,4,171,128,
      128,128,128,128,246,1,22,84,129,88,226,128,128,128,5,178,128,134,0,215,
      128,128,128,128>>:
Bin <<192,248,224,208,4,101,182,35,99,59,122,65,97,19,227,129,140,247,30,112,
      70,199,35,254,3,39,132,128,128,128,128,29,236,128,40,125,15,251,4,172,
      128,128,128,128>>:
Bin <<192,248,224,208,4,101,183,35,99,59,122,65,97,21,158,129,140,246,30,112,
      70,199,35,254,3,39,133,128,128,128,128,24,128,128,40,125,17,181,2,250,
      128,128,128,128>>:
Bin <<192,248,224,208,4,101,184,35,99,59,122,65,97,23,183,129,140,247,30,112,
      70,199,35,254,3,39,134,128,128,128,128,30,133,128,40,125,19,204,4,173,
      128,128,128,128>>:

данные есть, но они от vlc
vlc настроен на получение sourse specific multicast, поэтому данные идут,
erl настроен на any-source multicast и поэтому он не может подключиться к источнику.
так вот вопрос в том, как настроить erlang на самостоятельное получение ssm?

Max Lapshin

unread,
Jul 15, 2014, 10:53:42 AM7/15/14
to erlang-...@googlegroups.com
Пробовали указать не   {add_membership,{IpAddress,{0,0,0,0}}} ,  а {add_membership,{IpAddress,{172,27,129,77}}}  ?

Анастасия Субботина

unread,
Jul 15, 2014, 11:04:31 AM7/15/14
to erlang-...@googlegroups.com
да, пробовала, безрезультатно.

вторник, 15 июля 2014 г., 18:53:42 UTC+4 пользователь Max Lapshin написал:

Alex Grigorovich

unread,
Jul 15, 2014, 2:16:48 PM7/15/14
to erlang-...@googlegroups.com
2014-07-15 16:05 GMT+07:00 Анастасия Субботина <spasen...@gmail.com>:
> vlc настроен на получение sourse specific multicast, поэтому данные идут,
> erl настроен на any-source multicast и поэтому он не может подключиться к
> источнику.
> так вот вопрос в том, как настроить erlang на самостоятельное получение ssm?

Ради прокрастинации немного поизучал вопрос; выяснилось следующее.

Плохая для вас новость: текущий эрланг не поддерживает source specific
multicast.

Хорошая новость: добавить поддержку SSM можно несложным патчем к
эрлангу, если вы готовы идти этой дорогой. Патч в аттаче, наверное
работает (проверить толком не могу, но запросы, похожие на те, что
надо, шлёт). Также в аттаче немного модифицированный тестовый клиент.

Сборка:

- вытащить исходники эрланга
- накатить патч:
cd $erlang_tree; patch -p1 < /path/to/erlang-udp-ssm.patch
- собрать эрланг, последовательностью команд в духе
./otp_build autoconf
./configure
make
./otp_build update_preloaded --no-commit
make
make install

--
Удачи,
Алексей.
erlang-udp-ssm.patch
udp_bin_ssm.erl

Анастасия Субботина

unread,
Jul 15, 2014, 9:25:16 PM7/15/14
to erlang-...@googlegroups.com
Спасибо

Alex Grigorovich

unread,
Jul 16, 2014, 1:54:33 AM7/16/14
to erlang-...@googlegroups.com
Апдейт: патч не нужен: можно нужную опцию передать в виде

{raw,0,39,<<16#e2000000:32,16#0:32,16#01010101:32>>}

Порядок адресов -- IP группы, IP интерфейса и IP источника. Значение
опции приведено для Linux; для FreeBSD или OS X возможно придется
заменить 39 на значение IP_ADD_SOURCE_MEMBERSHIP из
/usr/include/netinet/in.h .

http://erlang.org/pipermail/erlang-questions/2009-June/044505.html

--
Алексей

Анастасия Субботина

unread,
Jul 16, 2014, 3:06:12 AM7/16/14
to erlang-...@googlegroups.com
Спасибо еще раз

среда, 16 июля 2014 г., 9:54:33 UTC+4 пользователь Alex Grigorovich написал:

Анастасия Субботина

unread,
Jul 16, 2014, 7:10:00 AM7/16/14
to erlang-...@googlegroups.com
Может первый вариант все же более доступен, а то не совсем понятно что с этим '{raw,0,39,<<16#e2000000:32,16#
0:32,16#01010101:32>>}' делать.

Alex Grigorovich

unread,
Jul 16, 2014, 7:48:18 AM7/16/14
to erlang-...@googlegroups.com
2014-07-16 18:10 GMT+07:00 Анастасия Субботина <spasen...@gmail.com>:
> Может первый вариант все же более доступен, а то не совсем понятно что с
> этим '{raw,0,39,<<16#e2000000:32,16#0:32,16#01010101:32>>}' делать.

Вызов gen_udp:open тут будет выглядеть как-то так:

{ok,Socket} = gen_udp:open(erlang:list_to_integer(Port),
[
inet,
binary,
{active,true},
{reuseaddr,true},
{multicast_ttl, 30},
{raw, 0, 39, <<ip_to_binary(GroupAddress)/binary,
ip_to_binary({0,0,0,0})/binary, ip_to_binary(SourceAddress)/binary>>}
]),

где ip_to_binary -- это

ip_to_binary(Ip) -> list_to_binary(tuple_to_list(Ip)).

--
Алексей

Анастасия Субботина

unread,
Jul 16, 2014, 7:59:24 AM7/16/14
to erlang-...@googlegroups.com
Спасибо

среда, 16 июля 2014 г., 15:48:18 UTC+4 пользователь Alex Grigorovich написал:

Анастасия Субботина

unread,
Jul 16, 2014, 9:32:30 AM7/16/14
to erlang-...@googlegroups.com
Чего то не хватает коду
-module(udp_bin_ssm).
-compile([export_all]).

start
([Source,Group,Port]) ->
   
{ok,SourceAddress} = inet:parse_address(Source),
   
{ok,GroupAddress} = inet:parse_address(Group),
   
   
{ok,Socket} = gen_udp:open(erlang:list_to_integer(Port),
       
[
            inet
,
            binary
,
           
{active,true},
           
{reuseaddr,true},
           
{multicast_ttl, 30},
       
{raw, 0, 39, << ip_to_binary(GroupAddress)/binary,   %%15

        ip_to_binary
({0,0,0,0})/binary,
        ip_to_binary
(SourceAddress)/binary >>}
       
]),

    io
:format("Socket ~p:~n", [Socket]),
   
Pid = spawn(fun() -> loop(Socket) end),
    io
:format("Pid :~p~n",[Pid]),            
    ok
= gen_udp:controlling_process(Socket,Pid).
 
ip_to_binary
(Ip) ->
    list_to_binary
(tuple_to_list(Ip)).


loop
(Socket) ->
    receive
       
{udp,_Socket,_SrcAddr,_Port,Bin} ->
            io
:format("Bin ~p:~n", [Bin]),
         
            loop
(Socket);
       
Msg ->
            io
:format("Msg ~p:~n", [Msg])
   
end.

16> c(udp_bin_ssm).
udp_bin_ssm.erl:15: syntax error before: '('
error

среда, 16 июля 2014 г., 15:59:24 UTC+4 пользователь Анастасия Субботина написал:

Max Lapshin

unread,
Jul 16, 2014, 9:33:47 AM7/16/14
to erlang-...@googlegroups.com
Ух-ты, вот это хитрость.

Спасибо за патч!


--

Dmitry Bushmelev

unread,
Jul 16, 2014, 9:41:09 AM7/16/14
to erlang-...@googlegroups.com
start([Source,Group,Port]) ->
    {ok, SourceAddress} = inet:parse_address(Source),
    {ok, GroupAddress} = inet:parse_address(Group),
    LocalIp = ip_to_binary({0, 0, 0, 0}),
    GroupIp = ip_to_binary(GroupAddress),
    SourceIp = ip_to_binary(SourceAddress),
    Bin = <<GroupIp/binary, LocalIp/binary, SourceIp/binary>>,
    {ok, Socket} = gen_udp:open(erlang:list_to_integer(Port),
                                [inet,
                                 binary,
                                 {active,true},
                                 {reuseaddr,true},
                                 {multicast_ttl, 30},
                                 {raw, 0, 39, Bin}]),
    io:format("Socket ~p:~n", [Socket]),
    Pid = spawn(fun() -> loop(Socket) end),
    io:format("Pid :~p~n",[Pid]),
    ok = gen_udp:controlling_process(Socket, Pid).

][azar

unread,
Jul 16, 2014, 9:55:39 AM7/16/14
to erlang-...@googlegroups.com
Выражение перед /binary должно быть в скобках
...
(ip_to_binary({0,0,0,0}))/binary,
(ip_to_binary
(SourceAddress))/binary

...


16 июля 2014 г., 17:32 пользователь Анастасия Субботина <spasen...@gmail.com> написал:
--

Анастасия Субботина

unread,
Jul 16, 2014, 10:32:44 AM7/16/14
to erlang-...@googlegroups.com
Всем спасибо за помощь, процесс пошел.

Анастасия Субботина

unread,
Aug 27, 2014, 11:23:42 AM8/27/14
to erlang-...@googlegroups.com
Пытаюсь переделать полученный код в Erlang/OTP но не получается
-module(fast_server).
-behaviour(gen_server).

-compile(export_all).
-record(state, {
    socket,
    buffer
}).

start_link() ->
    gen_server:start_link(?MODULE, [], []).

init([]) ->

    Source = "172.27.129.77",
    Port = "24027",
    Group = "239.192.7.27",


    {ok,SourceAddress} = inet:parse_address(Source),
    {ok,GroupAddress} = inet:parse_address(Group),
        GroupIp = ip_to_binary(GroupAddress),
        LocalIp = ip_to_binary({0,0,0,0}),

        SourceIp = ip_to_binary(SourceAddress),
        Bin = << GroupIp/binary,LocalIp/binary,SourceIp/binary >>,
    {ok, Socket} = gen_udp:open(erlang:list_to_integer(Port),

      [
         inet,
         binary,
         {active, true},
         {reuseaddr, true},
    {multicast_ttl, 30},
         {raw, 0, 39, Bin}
      ]),
    Pid = gen_server:cast(self(), Socket),
    gen_udp:controlling_process(Socket, Pid),  %% 35
    {ok, #state{socket = Socket}}.

ip_to_binary(Ip) ->
    list_to_binary(tuple_to_list(Ip)).

handle_cast(Socket, #state{} = Server) ->
    case Socket of
    {udp, _Socket, _Ip, _Port, Bin} ->

        io:format("Bin ~p:~n", [Bin]),
    handle_cast(Socket, #state{buffer = Bin});
    _Msg ->
        {noreply, Server}
    end.

и ошибка

1> application:start(fast).
ok
2> fast_server:start_link().
** exception exit: function_clause
     in function  inet:udp_controlling_process/2
        called as inet:udp_controlling_process(#Port<0.659>,ok)
     in call from fast_server:init/1 (src/fast_server.erl, line 35)
     in call from gen_server:init_it/6 (gen_server.erl, line 306)
     in call from proc_lib:init_p_do_apply/3 (proc_lib.erl, line 239)

в чем причина?


понедельник, 17 февраля 2014 г., 9:45:13 UTC+4 пользователь Анастасия Субботина написал:
Я настраиваю получение данных по udp, написала код для проверки самого факта получения

-module(udp_bin).
-compile([export_all]).

start([Host,Port]) ->
    {ok,IpAddress} = inet_parse:address(Host),
    {ok,Socket} = gen_udp:open(erlang:list_to_integer(Port),
        [
           
            binary,
            {active,true},
            {reuseaddr,true}
           
        ]),
    inet:setopts(Socket,[{add_membership,{IpAddress,{0,0,0,0}}}]),
    io:format("Socket ~p:~n", [Socket]),
    Pid = spawn(fun() -> loop(Socket) end),              %%15
    ok = gen_udp:controlling_process(Socket,Pid).


loop(Socket) ->
    receive
        {udp,_Socket,_SrcAddr,_Port,Bin} ->
            io:format("Bin ~p:~n", [Bin]),           %%25
            loop(Socket)

набираю следующие команды

1> A = ["239.192.7.27","24027"].
["239.192.7.27","24027"]
4> udp_bin:start(A).
Socket #Port<0.2400>:
ok

что изменить что бы начать получать данные?

Andrew Gopienko

unread,
Aug 27, 2014, 11:26:58 AM8/27/14
to erlang-...@googlegroups.com
gen_server:cast никак не Pid возвращает


27 августа 2014 г., 22:23 пользователь Анастасия Субботина <spasen...@gmail.com> написал:
--

Анастасия Субботина

unread,
Aug 27, 2014, 12:39:31 PM8/27/14
to erlang-...@googlegroups.com
спасибо

Анастасия Субботина

unread,
Aug 28, 2014, 1:28:14 AM8/28/14
to erlang-...@googlegroups.com
Я внесла изменения вместо
Pid = gen_server:cast(self(), Socket),
сделала
{ok, Pid} = fast:start_link(self()).
ну и соответственно дополнительный модуль
-module(fast).
-behaviour(gen_server).

-compile(export_all).

start_link(Id) ->
    gen_server:start_link(?MODULE,[Id],[]).

init([_Id]) ->
    {ok, []}.
и результат получился следующий
erl -pa ./ebin

Erlang/OTP 17 [erts-6.1] [source] [64-bit] [smp:8:8] [async-threads:10] [kernel-poll:false]

Eshell V6.1  (abort with ^G)
1> application:start(fast).
ok
2> Pid = fast:start_link(test).
{ok,<0.41.0>}
3> fast_server:start_link().
{ok,<0.43.0>}
4>
=ERROR REPORT==== 28-Aug-2014::08:53:06 ===
** Generic server <0.44.0> terminating
** Last message in was {udp,#Port<0.662>,
                            {172,27,129,77},
                            1412,
                            <<192,248,192,172,5,210,35,99,63,31,40,125,82,232>>}
** When Server state == []
** Reason for termination ==
** {'function not exported',
       [{fast,terminate,
            [{undef,
                 [{fast,handle_info,
                      [{udp,#Port<0.662>,
                           {172,27,129,77},
                           1412,
                           <<192,248,192,172,5,210,35,99,63,31,40,125,82,232>>},
                       []],
                      []},
                  {gen_server,handle_msg,5,
                      [{file,"gen_server.erl"},{line,599}]},
                  {proc_lib,init_p_do_apply,3,
                      [{file,"proc_lib.erl"},{line,239}]}]},
             []],
            []},
        {gen_server,terminate,6,[{file,"gen_server.erl"},{line,721}]},
        {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,239}]}]}
** exception error: undefined function fast:terminate/2
     in function  gen_server:terminate/6 (gen_server.erl, line 721)

     in call from proc_lib:init_p_do_apply/3 (proc_lib.erl, line 239)
а здесь что не так? и чем отличается {ok, Pid} = fast:start_link(self()) от  Pid = fast:start_link(self()) ?

mprize

unread,
Aug 28, 2014, 1:59:15 AM8/28/14
to erlang-...@googlegroups.com
добавь ещё handle_info и terminate в модуль. Он пытается вызвать handle_info, не находит, падает, пытается вызвать после падения terminate, не находит и опять падает

mprize

unread,
Aug 28, 2014, 2:02:22 AM8/28/14
to erlang-...@googlegroups.com
только матчингом результата. В первом случае в Pid окажется pid, а во втором - tuple

Анастасия Субботина

unread,
Aug 28, 2014, 2:15:00 AM8/28/14
to erlang-...@googlegroups.com
А если не в отдельном модуле запускать fast:start_link(test), а перенести в один модуль fast_server и сделать в нем что то подобное?

mprize

unread,
Aug 28, 2014, 2:16:05 AM8/28/14
to erlang-...@googlegroups.com
брррр, ничего не понимаю

mprize

unread,
Aug 28, 2014, 2:22:41 AM8/28/14
to erlang-...@googlegroups.com
в смысле - в fast_server добавить функцию start_link и использовать её для запуска fast_server? Нормально.


On Thursday, August 28, 2014 10:15:00 AM UTC+4, Анастасия Субботина wrote:

Анастасия Субботина

unread,
Aug 28, 2014, 2:59:48 AM8/28/14
to erlang-...@googlegroups.com
Если добавляю handle_info в модуль fast, то соответственно данные я буду получать в этом модуле, так как controlling_process передан в этот модуль, я правильно понимаю?

mprize

unread,
Aug 28, 2014, 3:02:31 AM8/28/14
to erlang-...@googlegroups.com
да, так. По стек-трейсу видно, что вызывается модуль fast. И для terminate, и для handle_info

{'function not exported',
       [{fast,terminate,
            [{undef,
                 [{fast,handle_info,

Artem Golovinsky

unread,
Aug 28, 2014, 4:21:15 AM8/28/14
to erlang-...@googlegroups.com
Ну Вы хоть посмотрите на стектрейс то, а?
Pid = gen_server:cast(self(), Socket), %% Pid - это будет 'ok' потому что cast всегда возвращает ok
Потом вы его передаете в gen_udp:controlling_process(Socket, Pid), 
Об это говорит стектрейс:

in function  inet:udp_controlling_process/2
        called as inet:udp_controlling_process(#Port<0.659>,ok)



27 августа 2014 г., 19:23 пользователь Анастасия Субботина <spasen...@gmail.com> написал:
--
Вы получили это сообщение, поскольку подписаны на группу "Erlang по-русски".
Чтобы отменить подписку на эту группу и больше не получать от нее сообщения, отправьте письмо на электронный адрес erlang-russia...@googlegroups.com.
Чтобы отправлять сообщения в эту группу, отправьте письмо на электронный адрес erlang-...@googlegroups.com.
Чтобы настроить другие параметры, перейдите по ссылке https://groups.google.com/d/optout.



--
Best regards,
Artem Golovinsky

Artem Golovinsky

unread,
Aug 28, 2014, 4:22:46 AM8/28/14
to erlang-...@googlegroups.com
И не вздумайте из init'а вызывать gen_server:call/2 к самому себе


28 августа 2014 г., 4:21 пользователь Artem Golovinsky <artemgo...@gmail.com> написал:

Анастасия Субботина

unread,
Aug 28, 2014, 6:35:06 AM8/28/14
to erlang-...@googlegroups.com
Посмотреть то я могу, боюсь что я пока все равно не вижу, нет у меня опыта. А вызывать gen_server:call в планах не было.

Анастасия Субботина

unread,
Sep 3, 2014, 7:04:02 AM9/3/14
to erlang-...@googlegroups.com
Переписываю этот код на OTP и никак не могу найти решения для следующего участка
decode(Context, Binary, BinaryOutput) ->
    case erlang_fast:decode(Binary, Context) of
        {ok, {TemplateName, Msg, Rest, _}} ->
            io:format("~p ~p~n", [TemplateName, Msg]),
            decode(Context, Rest, BinaryOutput);
        {error, Reason} ->
            io:format("ERROR: ~p, Bin = ~p ~n", [Reason, Binary]),
            exit(failed)
    end.
следующее решение
handle_info({udp, _Socket, _Ip, _Port, Bin}, #context{} = Context) ->
    case fast_cont:decode(Bin, Context) of
        {ok, {TemplateName, Msg, Rest, _}} ->
            io:format("~p ~p~n", [TemplateName, Msg]),
            %{noreply, Context}
            {ok,{_, _, _, Context1}} = fast_cont:decode(Rest,Context),
            handle_info({udp, _Socket, _Ip, _Port, Rest}, Context1);
        {ok, {TemplateName, Msg, << >>, _}} ->
            io:format("~p ~p~n", [TemplateName, Msg]);
        {error, Reason} ->
            io:format("ERROR: ~p, Bin = ~p ~n", [Reason, Bin]),
            exit(failed)
       
    end;
выдает ошибку

Eshell V6.1  (abort with ^G)
1> application:start(fast).
ok
2> fast:start_link(test).

{ok,<0.41.0>}
3> fast_server:start_link().
{ok,<0.43.0>}
<<"Reset">> []
** exception error: no function clause matching
                    fast:terminate({{badmatch,{error,undef}},
                                    [{fast,handle_info,2,[{file,"src/fast.erl"},{line,32}]},
                                     {gen_server,handle_msg,5,
........
как можно изменить {ok,{_, _, _, Context1}} = fast_cont:decode(Rest,Context), чтобы работало?

mprize

unread,
Sep 3, 2014, 9:41:28 AM9/3/14
to erlang-...@googlegroups.com
1 - в какой модуль ты эту handle_info пихаешь - fast или fast_server? В эксепшене мелькает undef рядом с fast,handle_info, правда эксепшн выглядит как-то странно.
2 - внутри одной handle_info два раза вызывать decode - это специально? Я бы попробовал вызывать decode один раз и уже ответ валить снова на handle_info (отправкой сообщения, а не вызовом функции), чтобы handle_info разбирала очередной этап. Т.е. decode вернул Result, ты берёшь и шлёшь: {decode_result, Result} ! Pid
3 - что, вообще, надо? Я не успеваю уследить

mprize

unread,
Sep 3, 2014, 9:49:40 AM9/3/14
to erlang-...@googlegroups.com
да, кстати, из handle_info лучше бы возвращать что-нибудь приличное, типа {noreply, State} или {stop, State, Reason}

Анастасия Субботина

unread,
Sep 3, 2014, 10:09:44 AM9/3/14
to erlang-...@googlegroups.com
Я получаю сообщение,состоящее из 2-х частей, первую часть я получаю следующим кодом

handle_info({udp, _Socket, _Ip, _Port, Bin}, #context{} = Context) ->
    case fast_cont:decode(Bin, Context) of
        {ok, {TemplateName, Msg, Rest, _}} ->
            io:format("~p ~p~n", [TemplateName, Msg]),
            {noreply, Context}
end;
выглядит она так

<<"Reset">> [] и интереса из себя никаго не представляет


самое интересное остается в Rest, вот я и пытаюсь его извлечь, в полном виде это выглядит так
<<"Reset">> []
<<"DefaultIncrementalRefreshMessage">> [{<<"ApplVerID">>,<<"8">>},
                                        {<<"MessageType">>,<<"X">>},
                                        {<<"SenderCompID">>,<<"RTS">>},
                                        {<<"MsgSeqNum">>,313667},
                                        {<<"SendingTime">>,20140903140743884},
                                        {<<"MDEntries">>,
                                         [[{<<"MDUpdateAction">>,0},
                                           {<<"MDEntryType">>,<<"w">>},
                                           {<<"SecurityID">>,55858246},
                                           {<<"SecurityIDSource">>,8},
                                           {<<"ExchangeTradingSessionID">>,
                                            4644},
                                           {<<"RptSeq">>,23244},
                                           {<<"MDEntrySize">>,66},
                                           {<<"MDEntryTime">>,140729264},
                                           {<<"NumberOfOrders">>,4}],
                                          [{<<"MDUpdateAction">>,0},
                                           {<<"MDEntryType">>,<<"v">>},
                                           {<<"SecurityID">>,64758598},
                                           {<<"SecurityIDSource">>,8},
                                           {<<"ExchangeTradingSessionID">>,
                                            4644},
                                           {<<"RptSeq">>,149064},
                                           {<<"MDEntrySize">>,3024},
                                           {<<"MDEntryTime">>,140729261},
                                           {<<"NumberOfOrders">>,279}],
                                          [{<<"MDUpdateAction">>,0},
                                           {<<"MDEntryType">>,<<"v">>},
                                           {<<"SecurityID">>,64759366},
                                           {<<"SecurityIDSource">>,8},
                                           {<<"ExchangeTradingSessionID">>,
                                            4644},
                                           {<<"RptSeq">>,85517},
                                           {<<"MDEntrySize">>,8299},
                                           {<<"MDEntryTime">>,140729282},
                                           {<<"NumberOfOrders">>,184}],
                                          [{<<"MDUpdateAction">>,0},
                                           {<<"MDEntryType">>,<<"w">>},
                                           {<<"SecurityID">>,64759366},
                                           {<<"SecurityIDSource">>,8},
                                           {<<"ExchangeTradingSessionID">>,
                                            4644},
                                           {<<"RptSeq">>,85518},
                                           {<<"MDEntrySize">>,4961},
                                           {<<"MDEntryTime">>,140729282},
                                           {<<"NumberOfOrders">>,139}],
                                          [{<<"MDUpdateAction">>,0},
                                           {<<"MDEntryType">>,<<"w">>},
                                           {<<"SecurityID">>,66490694},
                                           {<<"SecurityIDSource">>,8},
                                           {<<"ExchangeTradingSessionID">>,
                                            4644},
                                           {<<"RptSeq">>,36762},
                                           {<<"MDEntrySize">>,657},
                                           {<<"MDEntryTime">>,140729275},
                                           {<<"NumberOfOrders">>,28}],
                                          [{<<"MDUpdateAction">>,0},
                                           {<<"MDEntryType">>,<<"v">>},
                                           {<<"SecurityID">>,67225414},
                                           {<<"SecurityIDSource">>,8},
                                           {<<"ExchangeTradingSessionID">>,
                                            4644},
                                           {<<"RptSeq">>,46351},
                                           {<<"MDEntrySize">>,26},
                                           {<<"MDEntryTime">>,140729274},
                                           {<<"NumberOfOrders">>,13}]]}]
повторный handle_info я отправляю в fast, своего рода второй loop

mprize

unread,
Sep 3, 2014, 10:53:20 AM9/3/14
to erlang-...@googlegroups.com
эх, без полного текста программы непонятно. Есть мысль: в эксепшене участвует {badmatch,{error,undef}}. Возможно где-то происходит вызов неизвестной функции, он ловится catch и возвращается как {error, undef} для decode.
Пример: try binary:undefined_01() catch T:R -> {T,R} end. Вернёт {error, undef}. Этот результат уходит в decode.
А уже потом где-то в процессе декодирования что-то падает с badmatch - ну оно же ждёт бинарь, а не tuple.
Это только подозрения, конечно.

Анастасия Субботина

unread,
Sep 3, 2014, 2:17:12 PM9/3/14
to erlang-...@googlegroups.com

mprize

unread,
Sep 3, 2014, 4:15:51 PM9/3/14
to erlang-...@googlegroups.com
у меня подозрение, что fast:handle_info в строке 41:
      {ok, { _, _, _, Context1}} = fast_segment:decode(Rest, Context)
возвращает {error, undef}. Ну и падает с badmatch. Почему он такое возвращает только во второй раз - непонятно.
Трассировкой с dbg не хочешь заняться? Она всё покажет.
Впрочем, для начала можно посмотреть - что функция возвращает. Разбей эту строку так:

Res = fast_segment:decode(Rest, Context),
io:format("res: ~p~n", [Res]),
 {ok, { _, _, _, Context1}}  = Res

Заодно - выкинь import. Поставь полное обращение к модулю. Может там что-то где-то влияет, так сразу не видно пока

Анастасия Субботина

unread,
Sep 3, 2014, 11:24:45 PM9/3/14
to erlang-...@googlegroups.com
Спасибо, будем пробовать.
Reply all
Reply to author
Forward
0 new messages