сокеты erlang и gen_server - данные не принимаются на стороне сервера

В двух словах: я пытаюсь создать сервер сокетов, к которому клиенты подключаются и отправляют/получают сообщения (на основе кода sockserv в руководстве Learn you some erlang http://learnyousomeerlang.com/buckets-of-sockets) Серверные компоненты: супервизор - уникальный, запускается в самом начале, порождает процессы с Поведение gen_server Процессы поведения gen_server - каждый из них имеет дело с соединением.

Сторона клиента: клиент, который подключается к сокету и отправляет несколько байтов данных, а затем отключается.

Подробности кода Мой код почти такой же, как в представленном туториале. Начальник идентичен. Компонент gen_server упрощен, так что он имеет только один кейс handle_info, который должен ловить все и просто печатать.

Проблема Соединение установлено успешно, но когда клиент отправляет данные, сервер ведет себя так, как будто данные не получены (я ожидаю, что в этом случае будет вызвана функция handle_info).

handle_info действительно вызывается, но только когда клиент отключается, и об этом событии сообщается с сообщением.

Мои попытки Я экспериментировал с разными клиентами, написанными на Erlang или Java, я пытался установить активное/пассивное состояние сокета. Автор туториала устанавливает {active, Once} после отправки сообщения. В итоге я просто установил {active, true} после создания AcceptSocket как такового: (процесс gen_server инициализируется состоянием, которое содержит исходный ListenSocket, созданный супервизором)

handle_cast(accept, S = #state{socket=ListenSocket}) ->

     {ok, AcceptSocket} = gen_tcp:accept(ListenSocket),
     io:format("accepted connection ~n", []),

      sockserv_sup:start_socket(), % a new acceptor is born, praise the lord
      inet:setopts(AcceptSocket, [{active, true}]),
      send(AcceptSocket, "Yellow", []),
      {noreply, S#state{socket=AcceptSocket, next=name}}.

send(Socket, Str, Args) ->
    ok = gen_tcp:send(Socket, io_lib:format(Str++"~n", Args)),
    ok.

   handle_info(E, S) ->
       io:format("mothereffing unexpected: ~p~n", [E]),
       {noreply, S}.

Это не имеет абсолютно никакого эффекта. handle_info вызывается только тогда, когда соединение потеряно из-за отключения клиента. всякий раз, когда клиент отправляет данные, ничего не происходит.

В чем может быть проблема? Я потратил довольно много времени на это, я действительно понятия не имею. Большое спасибо.


person dandroid    schedule 19.11.2012    source источник


Ответы (2)


Пробовали ли вы устанавливать другие параметры на http://www.erlang.org/doc/man/inet.html#setopts-2

inet:setopts(AcceptSocket, [{active, true}])

Например:

{packet, line} для чтения построчно

и

binary для чтения данных в виде двоичного файла.

Я также недавно работал над аналогичным упражнением, основанным на этом руководстве, и мои варианты были такими:

inet:setopts(LSocket, [{active,true}, {packet, line}, binary, {reuseaddr, true}]),

person Tom H.    schedule 19.11.2012
comment
Я пробовал эти варианты. Они не имеют никакого эффекта. Я пробовал простое взаимодействие между сокетом сервера и сокетом клиента, и это работает. Но каким-то образом в этом контексте, когда сокет обрабатывается gen_server, и он должен запускать свою функцию handle_info, это не работает. - person dandroid; 19.11.2012

В заключение обратите внимание на варианты. Я действительно не обращал внимания на последствия набора опций. Я попробовал с более суженной ситуацией и разобрался. Моя проблема заключалась в опции {packet, line}, которая подразумевает, что \n считается разделителем сообщений.

person dandroid    schedule 23.11.2012