Erlang gen_tcp: listen / 2 для IPv6 - PullRequest
       38

Erlang gen_tcp: listen / 2 для IPv6

2 голосов
/ 23 ноября 2011

Я отправляю отправителю .NET TCP отправителю Erlang.Компоненту .NET нравится использовать адрес IPv6 ::1 при разрешении localhost.Я не совсем уверен, как заставить Эрланга прослушивать IPv6-адрес с помощью gen_tcp.Вот моя попытка.Я говорю не ту розетку для прослушивания?Спасибо!

listen(Config) ->
    PortString = Config#cfg.eventbusport,
    GoodPort = check_int(PortString),
    Port = if GoodPort -> 
               list_to_integer(PortString);
           true ->
               ?DEFAULT_PORT
           end,                      %% IPv6 here --->
    {ok, XSocket} = gen_tcp:listen(Port, [binary, {packet, line}, {active, false}, {reuseaddr, true}, inet6, {ip, {0,0,0,0,0,0,0,1}}])
    end,
    accept(XSocket, Config).

accept(LSocket, Config) ->
    case gen_tcp:accept(LSocket) of
        {ok, Socket} ->
            spawn_link(fun() -> loop(Socket, Config) end),
            accept(LSocket, Config);
        {error, closed} ->
            logger("Accept: Closed socket.",[],1),
            listen(Config)
    end.

loop(Socket, Config) ->
    case inet:setopts(Socket, [{recbuf, 64000}]) of
        ok ->
            case gen_tcp:recv(Socket, 0) of
                {ok, Data} ->
                    SplitData = binary:split(Data,?CRLF,[global]),
                    discrim(SplitData, Config),
                    loop(Socket, Config);
                {error, closed} ->
                    logger("Loop: Closed socket.",[],1),
                    ok
            end;
        {error, Reason} ->
            logger("ERROR: Couldn't set the recbuf to 64k! Because ~p",[Reason],1)
    end.

1 Ответ

1 голос
/ 26 ноября 2011

Какова реальная проблема, с которой вы столкнулись?

Вы, вероятно, должны установить процесс управления сокетом на процесс, который вы породили, чтобы использовать соединение. Так что в вашем accept/2 вы бы сделали что-то вроде:

accept(LSocket, Config) ->
    case gen_tcp:accept(LSocket) of
        {ok, Socket} ->
            Pid = spawn_link(fun() -> loop(Socket, Config) end),
            gen_tcp:controlling_process(Socket, Pid),
            accept(LSocket, Config);
...

Другим способом написания цикла принятия является создание новых циклов принятия. Вы получаете что-то вроде:

accept_loop(LSocket, Config) ->
    {ok,Socket} = gen_tcp:accept(LSocket),
    spawn_link(fun() -> accept_loop(LSocket, Config) end),
    loop(Socket, Config).

Это без обработки ошибок. Вы можете без проблем передать сокет прослушивания другим процессам. Конечно, если процесс, открывший сокет прослушивания, умирает, сокет закрывается.

...