[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