gen_server, gen_tcp question
Eric Merritt
cyberlync@REDACTED
Wed Jul 17 15:59:14 CEST 2002
Kent,
Thanks allot this actually clears things up quite a
bit. I do have one question though, the rshell app you
mention does not seem to be in my erlang distro
(R8-1). Do you have any idea where I could get it
from? or do I need to recompile erlang with some
options set?
Thanks,
Eric
--- Kent Boortz <kent@REDACTED> wrote:
>
> Eric Merritt <cyberlync@REDACTED> writes:
> > As some of you may know I am fairly new to
> erlang. I
> > have been poking around a bit getting my feet wet,
> > messing with yaws, mnesia, etc. Well I am finally
> > getting around to coding a fairly heft application
> as
> > a learning exercise and I have hit a stumbling
> block.
> > I am just begining to write the tcp comm part of
> the
> > application, I would love to follow the otp
> practices
> > and make use of gen_server. There even seems to be
> > some arcane way for gen_tcp and gen_server to work
> > together for a module. I can't, for the life of
> me,
> > figure it out. The documentation is pretty sparse
> in
> > this area as well.
>
> If you talk about creating an application that
> listen to a port and
> accept an connection then I think they don't fit
> together as well as
> they should do. Some OTP applications bypass the
> gen_server module and
> use the sys module to use gen_tcp and still fit into
> the supervision
> model of Erlang/OTP. You can look at the source of
> ssl or the P9
> rshell application for an example of this. There is
> an ascii drawing
> in "$ERL_TOP/lib/rshell/src/rshell.erl" that show
> the supervisor
> structure.
>
> One problem is that we can't sit and wait for a
> connection in the
> blocking call gen_tcp:accept() because the
> application may get a code
> change system message. One way around this is to
> give a timeout of one
> second to gen_tcp:accept() to leave the call and
> pick up system
> messages if any and redo the accept call.
>
> A second problem that gen_tcp solves in an unusual
> way (a bit ugly in
> my opinion) is that after an accept of a connection
> in active mode
> messages with TCP data may be received to the
> message queue of the
> process calling gen_tcp:accept() before it has
> started a process to
> handle the specific connection. There is a function
> gen_tcp:controlling_process() that redirect these
> messages to a new
> process and, from what I have been told, actually
> move the TCP
> messages from the message queue of the first process
> to the new
> controlling process,
>
> kent
>
>
> init(Parent, Options) ->
> process_flag(trap_exit, true),
>
> Deb = sys:debug_options(?DBG_OPTS ++ Options),
> Port = get_port(Options),
> AcceptTimeout =
> case application:get_env(rshell,
> accept_timeout) of
> {ok, AcceptT} ->
> AcceptT;
> undefined ->
> 1000 %
> XXX: Create a macro!!!
> end,
>
> Opts =
> [
> {nodelay, true},
> {packet,raw},
> {reuseaddr,true}
> ],
>
> % We crash if we can't open the socket to listen
> {ok, ListenSocket} = gen_tcp:listen(Port, Opts),
>
> loop(Parent, Deb, ListenSocket, AcceptTimeout).
>
>
> loop(Parent, Deb, ListenSocket, AcceptTimeout) ->
> receive
> {system, From, Request} ->
> State = {ListenSocket, AcceptTimeout},
> sys:handle_system_msg(Request, From,
> Parent, ?MODULE, Deb, State);
> What ->
> NewDeb = sys:handle_debug(Deb, {?MODULE,
> write_debug}, rshell_listener,
> {in, What}),
> loop(Parent, NewDeb, ListenSocket,
> AcceptTimeout)
> case gen_tcp:accept(ListenSocket,
> AcceptTimeout) of
> {ok, Sock} ->
> case
> supervisor:start_child(rshell_connection_sup,
>
> [Sock]) of
> {ok,Pid} when pid(Pid) ->
>
> gen_tcp:controlling_process(Sock, Pid),
> loop(Parent, Deb,
> ListenSocket, AcceptTimeout);
> Other ->
> NewDeb =
> sys:handle_debug(Deb,
>
> {?MODULE, write_debug},
>
> rshell_listener,
>
> {start_child_result,
>
> Other}),
> gen_tcp:close(Sock),
> loop(Parent, NewDeb,
> ListenSocket, AcceptTimeout)
> end;
> {error, timeout} ->
> %% This is what we want to
> enable system events
> loop(Parent, Deb, ListenSocket,
> AcceptTimeout);
> Other ->
> NewDeb = sys:handle_debug(Deb,
>
> {?MODULE, write_debug},
>
> rshell_listener,
>
> {accept_result,Other}),
> loop(Parent, NewDeb,
> ListenSocket, AcceptTimeout)
> end
> end.
__________________________________________________
Do You Yahoo!?
Yahoo! Autos - Get free new car price quotes
http://autos.yahoo.com
More information about the erlang-questions
mailing list