Ște*_*tan 6 sockets erlang connect gen-tcp
我有一个问题:我想创建一个可以保持1M同时打开TCP连接的Erlang服务器.我调整了我的操作系统(Oracle Linux 7)来提高文件描述符.在服务器上我做gen_tcp:listen
// point_1
Socket = gen_tcp:accept
spawn(handle(Socket))//另一个线程
返回point_1
如果我按顺序连接没问题,在100秒内连接100K客户端; 但我没有更多的信仰.
如果我想以一种连续的方式连接它们,例如,只有大约80个连接来自100.
这就是我运行一切的方式:
erlc *.erl
erl +Q 134217727 +P 1000000 -env ERL_MAX_PORTS 40960000 -env ERTS_MAX_PORTS 40960000
Run Code Online (Sandbox Code Playgroud)
//启动一个将侦听端口9999的服务器
ex:start(1, 9999)
Run Code Online (Sandbox Code Playgroud)
// 100个客户端尝试在端口9999上连接
ex:connect_clients(100, 9999)
Run Code Online (Sandbox Code Playgroud)
我来告诉你一些代码:
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.
Run Code Online (Sandbox Code Playgroud)
我在这里看到至少两个问题:
你需要提高你的听力积压; 默认为5.您可以通过设置{backlog, N}监听选项来提高它,例如,{backlog, 1024}.
您的server/2函数有问题,因为它接受连接,然后生成一个新进程来运行,loop/1但它不会使该新进程成为接受套接字的控制进程.该loop/1函数尝试{active,once}在套接字上设置模式以尝试接收传入的消息,但由于它未在控制过程中运行,因此它不起作用.(您应该通过在那里inet_setopts/2说出来验证返回值ok = inet:setopts(S,[{active,once}]),.)
而不是产生循环,你应该生成一个新的接受器,如下所示:
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,server,[LS,Nr+1]),
loop(S);
Other ->
io:format("accept returned ~w - goodbye!~n",[Other]),
ok
end.
Run Code Online (Sandbox Code Playgroud)
使用这种方法,接受套接字的进程运行loop/1,因此不需要更改套接字的控制进程.
| 归档时间: |
|
| 查看次数: |
724 次 |
| 最近记录: |