[erlang-questions] should be a parallel tcp server, but can't connect to more than 1 client
Rapsey
rapsey@REDACTED
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 <erlang@REDACTED> 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 <rapsey@REDACTED>:
> > 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
> > erlang-questions@REDACTED
> > 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.htm>
More information about the erlang-questions
mailing list