[erlang-questions] gen_tcp:accept use within a gen_fsm process

7 views
Skip to first unread message

igwan

unread,
Jun 25, 2007, 7:41:48 AM6/25/07
to erlang-q...@erlang.org
Hello list,

I'm writing a small TCP test application. I want each TCP connection to
be handled by one gen_fsm process. I could have one 'acceptor' process
calling gen_tcp:accept, then spawning a gen_fsm for each accepted
incoming connection. But in the doc, I read that, since a recent version
of Erlang/OTP, I can have any number of processes waiting in a
gen_tcp:accept call, so I wouldn't need the acceptor process anymore. My
question is about best practice. Where would you call gen_tcp:accept in
the gen_fsm module ? Into the init/1 function ? Like this :

-module(tcptest_fsm).
-behaviour(gen_fsm).

init([Listen_socket] = Args) ->
{ok, Socket} = gen_tcp:accept(Listen_socket),
...
{ok, conn_accepted_state, SD}.


I'm not very confident about puting such a blocking call at the init
phase as the process wouldn't be initialized until a connection arrives
and thus not supervised (Am I right ?).
Or maybe the new possibility offered by gen_tcp:accept wasn't intended
for use within a OTP system ?

Thanks for your help.

igwan

Mazen Harake

unread,
Jun 25, 2007, 10:25:11 AM6/25/07
to igwan, erlang-q...@erlang.org
A good (better) idea would probably be to create the next state after
init as the accepting state...
E.g:
-module(tcptest_fsm).
-behaviour(gen_fsm).

init([Listen_socket] = Args) ->

{ok, conn_accept, SD}.

conn_accept(Listening_socket) ->


{ok, Socket} = gen_tcp:accept(Listen_socket),

{ok, conn_accept, SD}.

....

Listener then listens and gets {ok, LSock},
Then starts a gen_fsm and then send the first event with the LSock as
the argument.


On top of my head :)
Hope you follow what I mean :)

/Mazen

> _______________________________________________
> erlang-questions mailing list
> erlang-q...@erlang.org
> http://www.erlang.org/mailman/listinfo/erlang-questions
>


--
Mazen Harake <ma...@erlang-consulting.com>
Erlang Software Developer and Consultant,
Erlang Training & Consulting, Ltd

Mobile Phone: +44 (0)795 13 26 317
Office Phone: +44 (0)207 45 61 020
Office Address:
401 London Fruit & Wool Exchange
Brushfield St, London, E1 6EL
United Kingdom

This email and its attachments may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of "Erlang Training & Consulting, Ltd".

If you are not the intended recipient of this email and its attachments, you must take no action based upon them, nor must you copy or show them to anyone. Please contact the sender if you believe you have received this email in error.


Ulf Wiger (TN/EAB)

unread,
Jun 25, 2007, 10:43:05 AM6/25/07
to igwan, erlang-q...@erlang.org

You can pass along e.g. the parent pid to the
init/1 function, then use

proc_lib:init_ack(Parent, {ok, self()}

then perform your blocking call, and then:

gen_fsm:enter_loop(Module, Options, StateName, StateData, FsmName)

See the documentation on gen_fsm.

The enter_loop() function was introduced specifically
for this kind of thing.

BR,
Ulf W

igwan

unread,
Jun 25, 2007, 7:53:42 PM6/25/07
to Ulf Wiger (TN/EAB), erlang-q...@erlang.org
It works well. Thanks for pointing this out.
This blocking call stuff is unusual for me, but maybe I'm too used to
message passing and asynchronicity :)
I would have expected gen_tcp to send messages for incoming connections
attempts and let the code decide if it accepts the connection or not. As
far as I read in the doc, there's no means of refusing or selectively
ignoring an incoming tcp connection based on eg. origin IP address. You
must already have blindly accepted the TCP connection before you have
access to this info. Or am I missing something again ?
I see there exists a port and a linked-in driver for raw sockets (at
least for *nix OSes) on Jungerl. Has someone already implemented
transport protocols (TCP SCTP ...) directly inside the erlang VM ?

best regards,

igwan

Ulf Wiger (TN/EAB) a écrit :

Per Hedeland

unread,
Jun 26, 2007, 7:56:45 AM6/26/07
to ig...@free.fr, ulf....@ericsson.com, erlang-q...@erlang.org
igwan <ig...@free.fr> wrote:
>
>It works well. Thanks for pointing this out.
>This blocking call stuff is unusual for me, but maybe I'm too used to
>message passing and asynchronicity :)
>I would have expected gen_tcp to send messages for incoming connections
>attempts and let the code decide if it accepts the connection or not. As
>far as I read in the doc, there's no means of refusing or selectively
>ignoring an incoming tcp connection based on eg. origin IP address. You
>must already have blindly accepted the TCP connection before you have
>access to this info. Or am I missing something again ?

The latter is (again) a property of the underlying (standard) socket API
(as long as you're using SOCK_STREAM sockets such as TCP). This doesn't
imply that 'accept' has to be implemented as a blocking operation
though, in fact if you're brave you can use prim_inet:async_accept/2 on
the socket you got from gen_tcp:listen/2.

--Per Hedeland

Reply all
Reply to author
Forward
0 new messages