[erlang-questions] tcp data in a gen_fsm

Frans Schneider schneider@REDACTED
Sun Nov 29 14:39:12 CET 2015


I forgot to fetch the last state name and state data from the 
lists:foldl() as return values of the handle_info() in the code below.

On 11/29/2015 02:27 PM, Frans Schneider wrote:
> Dear list,
>
> I have a gen_fsm representing the tcp connection to a remote server 
> with 6 states defined. Tcp data is handled by handle_info with active 
> = once.Tcp packets can contain more than one commands/data items.
> I would like to feed the data into the different FSM states in the 
> same manner as with send_event() and not handle the different states 
> in separate handle_info clauses for the different states or a massive 
> handle_info clause with a huge case statement.
> Question is, can I call the state clauses like this or do I brake OTP 
> behavior?This is a client and blocking incoming data is not an issue.
>
> handle_info({tcp, Socket, Raw_data}, State_name, #state{buffer = 
> Buffer} = State) ->
>     {Datas, Buffer1} = unpack(<<Buffer/binary, Raw_data/binary>>),
>     lists:foldl(fun(Data, {StateName_in, State_in}) ->
>                         {next_state, StateName_out, State_out} = 
> ?MODULE:StateName_in({recv, Data}, State_in),
>             {StateName_out, State_out}
>         end, {State_name, State}, Datas),
>     inet:setopts(Socket, [{active, once}]),
>     {next_state, active, State#state{buffer = Buffer1}};
>
> I can of course use a seperate process for handling the tcp stuff 
> which makes the gen_fsm calls, but was just wondering if this could 
> work as well.
>
> Thanks,
>
> /Frans
The code now is:

handle_info({tcp, Socket, Raw_data}, State_name, #state{buffer = Buffer} 
= State) ->
     {Datas, Buffer1} = unpack(<<Buffer/binary, Raw_data/binary>>),
     {State_name1,
      State1} =  lists:foldl(
                   fun(Data, {StateName_in, State_in}) ->
                           {next_state, StateName_out, State_out} = 
?MODULE:StateName_in({recv, Data}, State_in),
               {StateName_out, State_out}
           end, {State_name, State}, Datas),
     inet:setopts(Socket, [{active, once}]),
     {next_state, State_name1, State1#state{buffer = Buffer1}};




More information about the erlang-questions mailing list