I have a problem: I want to create an Erlang server that can support a 1M open tcp connection 1M. I configured my OS (Oracle Linux 7) to raise file descriptors. On the server, I am doing gen_tcp: listen
// point_1
Socket = gen_tcp: accept
spawn (handle (Socket)) // another thread
back to point_1
If I connect in series, this is not a problem, after 100 seconds I connected 100K clients; but I had no complaints for more.
If I want to connect them using conncurent , only about 80 connections are made, for example, out of 100.
This is how I run everything:
erlc *.erl erl +Q 134217727 +P 1000000 -env ERL_MAX_PORTS 40960000 -env ERTS_MAX_PORTS 40960000
// start one server that will listen on port 9999
ex:start(1, 9999)
// 100 clients try to connect to port 9999
ex:connect_clients(100, 9999)
Let me show you the code:
start(Num,LPort) -> case gen_tcp:listen(LPort,[{active, false},{packet,2}]) of {ok, ListenSock} -> start_servers(Num,ListenSock), {ok, Port} = inet:port(ListenSock), Port; {error,Reason} -> {error,Reason} end. start_servers(0,_) -> ok; start_servers(Num,LS) -> spawn(?MODULE,server,[LS,0]), start_servers(Num-1,LS). server(LS, Nr) -> io:format("before accept ~w~n",[Nr]), case gen_tcp:accept(LS) of {ok,S} -> io:format("after accept ~w~n",[Nr]), spawn(ex,loop,[S]), server(LS, Nr+1); Other -> io:format("accept returned ~w - goodbye!~n",[Other]), ok end. loop(S) -> inet:setopts(S,[{active,once}]), receive {tcp,S, _Data} -> Answer = 1, gen_tcp:send(S,Answer), loop(S); {tcp_closed,S} -> io:format("Socket ~w closed [~w]~n",[S,self()]), ok end. client(PortNo) -> {ok,Sock} = gen_tcp:connect("localhost", PortNo, []). connect_clients(Number, Port) -> spawn(ex, client, [Port]), case Number of 0 -> ok; _ -> connect_clients(Number-1, Port) end.