[erlang-questions] should be a parallel tcp server, but can't connect to more than 1 client

Rapsey <>
Mon Jan 21 21:03:19 CET 2008


Thanks for the help. I guess I still have some C++ habits to forget :)


Sergej


On Jan 21, 2008 10:54 AM, Joe Armstrong <> wrote:

> What might have happened here is that the process owning the listening
> socket has died.
> Sockets are owned by the process that creates the socket. if the
> owning process dies the
> socket is closed.
>
> If you evaluate start() in the shell then the owning process is the
> shell command interpreter,
> which usually does not die. If you evaluate start() in some other
> process then it might have died in which case
> the listening socket will be closed.
>
> If you change accept_con to print an error you should see this:
>
> accept_conn(LSock) ->
>     case gen_tcp:accept(LSock) of
>         {ok, Sock} ->
>            spawn(fun() -> accept_conn(LSock) end),
>             handle_conn(Sock);
>        X ->
>               io:format("OOps:pn", [X])
>            true
>   end.
>
> The way I'd write accept_con (the way in the Erlang book) is like this:
>
> accept_conn(LSock) ->
>     {ok, Sock} = case gen_tcp:accept(LSock),
>     spawn(fun() -> accept_conn(LSock) end),
>     handle_conn(Sock).
>
> The way you write things is to silently swallow up the error return
> with no warnings, which make things difficult
> to debug since you get no indication of error. The Erlang way is to
> crash hard and early.
>
> If the process owning the listen socket has died then you need to make
> sure it lives
> forever. I'd add a sleep(infinity) to the code, like this:
>
> start() ->
>    case gen_tcp:listen(6002, [binary, {packet, 0}, {active, true},
> {reuseaddr, true}]) of
>        {ok, Sock} ->
>            spawn(fun() -> accept_conn(Sock) end), sleep(infinity);
>        {error, Reason} -> {error, Reason}
>    end.
>
> where
>
> sleep(T) -> receive after T -> void end.
>
>
> This version of start can be happily spawned - in the original version
> you must ensure that the process evaluating
> start() does not die.
>
> Hope this helps
>
> /Joe Armstrong
>
>
>
> 2008/1/21 Rapsey <>:
> > All this program does is listen on a socket, spawn a new process on
> every
> > connection and send a never ending stream of numbers to each client that
> > connects to it. The problem is that once 1 client is connected, no one
> else
> > can connect, even though a new acceptor process has been spawned.
> >
> >
> > start() ->
> >     case gen_tcp:listen(6002, [binary, {packet, 0}, {active, true},
> > {reuseaddr, true}]) of
> >         {ok, Sock} ->
> >             spawn(fun() -> accept_conn(Sock) end);
> >         {error, Reason} -> {error, Reason}
> >     end.
> >
> >
> > accept_conn(LSock) ->
> >     case gen_tcp:accept(LSock) of
> >         {ok, Sock} ->
> >             spawn(fun() -> accept_conn(LSock) end),
> >             handle_conn(Sock);
> >         _ ->
> >             true
> >     end.
> >
> > % wait for http request from browser
> > handle_conn(Sock) ->
> >     receive
> >         {tcp, RecSock, Data} ->
> >             send_stream(RecSock, 0);
> >         {tcp_closed, _} ->
> >             true
> >     end.
> >
> > send_stream(Sock, N) when N == 0 ->
> >     gen_tcp:send(Sock, "HTTP/1.1 200 OK\r\nContent-type:
> > text/html\r\n\r\n<html><head></head><body>WOHOO<br>"),
> >     send_stream(Sock, N + 1);
> > send_stream(Sock, N) ->
> >     case gen_tcp:send(Sock, integer_to_list(N)) of
> >         ok ->
> >             timer:sleep(1000),
> >             send_stream(Sock, N + 1);
> >         Any ->
> >             true
> >     end.
> >
> >
> > thank you,
> > Sergej
> >
> > _______________________________________________
> > erlang-questions mailing list
> > 
> > http://www.erlang.org/mailman/listinfo/erlang-questions
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20080121/dbf0d4a0/attachment.html>


More information about the erlang-questions mailing list