[erlang-questions] how to limit number of connections to gen_tcp?
Essien Essien
essiene@REDACTED
Tue May 26 23:37:58 CEST 2009
Hi Jarrod,
On Tue, May 26, 2009 at 8:11 PM, Jarrod Roberson <jarrod@REDACTED> wrote:
> On Tue, May 26, 2009 at 1:20 PM, Alin Popa <alin.popa@REDACTED> wrote:
>
> What I really want to be able to do is accept the connection and if
> max connections is exceeded send a message to the client that the
> server is overloaded and the close the connection. What I really can't
> figure out is how to pass around a "current connection count" to I
> can increment it and decrement it during accepts and disconnects.
Well, you are using synchronous accepts so, the only thing avaiable
for you to do, is to keep a secondary "watchdog" counter loop. So when
you recieve a new connection, you attempt to "register" it with the
counter_loop, if it returns 'ok' to you, you go ahead, if it returns,
'overloaded' to you, you notify the client and close the connection.
When a successfull connection eventually closes {tcp_close, ....}, you
"deregister" the connection. An example _untested_ implementation is
below. Hope that helps out a bit.
-module(linereceiver).
-export([start/0]).
-define(MAX_CONNECTION, 50).
sleep(T) ->
receive
after T ->
true
end.
start() ->
spawn(fun() ->
start_parallel_server(3000, ?MAX_CONNECTION),
sleep(infinity)
end).
start_parallel_server(Port, MaxConn) ->
{ok, Listen} = gen_tcp:listen(Port, [binary,
{packet,line},{reuseaddr, true},{active, true}]),
CounterPid = spawn(fun() -> counter_loop(0, ?MAX_CONNECTION) end),
spawn(fun() -> par_connect(Listen, CounterPid)end).
counter_loop(Count, MaxConn) ->
receive
{From, register} ->
verify_conn(From, Count, MaxConn);
{_Any, deregister} ->
counter_loop(Count - 1, MaxConn)
end.
verify_conn(Pid, MaxConn, MaxConn) ->
From ! {self(), overloaded},
counter_loop(MaxConn - 1, MaxConn);
verify_conn(Pid, Count, MaxConn) ->
From ! {self(), ok},
counter_loop(Count + 1, MaxConn).
par_connect(Listen, CounterPid) ->
{ok, Socket} = gen_tcp:accept(Listen),
spawn(fun() -> par_connect(Listen, Counter) end),
CounterPid ! {self(), register},
receive
{CounterPid, overloaded} ->
gen_tcp:send(Socket, "Too many connections"),
gen_tcp:close(Socket);
{CounterPid, ok} ->
inet:setopts(Socket, [{packet, line}, list, {nodelay, true},
{active, true}]),
io:format("Connection Made!~n"),
get_line(Socket, CounterPid)
end.
get_line(Socket, CounterPid) ->
receive
{tcp, Socket, Line} ->
io:format("Received Line:~p~n", [Line]),
get_line(Socket, CounterPid);
{tcp_closed, Socket} ->
CounterPid ! {self(), deregister},
io:format("Connection Closed!~n")
end.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
More information about the erlang-questions
mailing list