我正在用 Erlang 编写一个服务器,并想打开大量连接。问题是我在 16358 次 gen_tcp:connect/3
调用后收到 {error, eaddrnotavail} 。正如您在下面看到的,服务器非常简单。
我修改了我的 MacOS Yosemite 限制; ulimit -n
输出为 6553600。
我开始:
erl +Q 134217727 +P 1000000 -env ERL_MAX_PORTS 40960000 -env ERTS_MAX_PORTS 40960000
服务器:
-module(naive_server).
-author("Stefan Stan").
-compile(export_all).
start_server(Port) ->
Pid = spawn_link(fun() ->
{ok, Listen} = gen_tcp:listen(Port, [binary, {backlog, 6553600}]),
spawn(fun() -> acceptor(Listen, 0) end),
timer:sleep(infinity)
end),
{ok, Pid}.
acceptor(ListenSocket, Nr) ->
{ok, Socket} = gen_tcp:accept(ListenSocket),
io:format("Client nr ~p connected~n", [Nr]),
spawn(fun() -> acceptor(ListenSocket,Nr+1) end),
handle(Socket).
handle(Socket) ->
receive
{tcp, Socket, <<"quit", _/binary>>} ->
gen_tcp:close(Socket);
{tcp, Socket, Msg} ->
gen_tcp:send(Socket, Msg),
handle(Socket)
end.
客户端:
-module(naive_client).
-author("Stefan Stan").
%% API
-export([connect_clients/3, connect/1]).
connect(Port) ->
gen_tcp:connect({127,0,0,1}, Port, []).
connect_clients(Number, Port, List) when is_number(Number), Number >= 0, is_number(Port), Port>0 ->
F =
fun() ->
case Number of
0 -> {ok, lists:reverse(List)};
_ ->
{ok, Pid} = connect(Port),
NewList = [Pid|List],
connect_clients(Number-1, Port, NewList)
end
end,
spawn(F).
最佳答案
我认为,您可能已经用完了临时传出端口(由您的客户端使用)。你能跑吗:macosx$ sysctl net.inet.ip.portrange.first net.inet.ip.portrange.last
。
在我的机器上,它给了我:
net.inet.ip.portrange.first: 49152
net.inet.ip.portrange.last: 65535
差值是16383,和你的号码很接近。
关于macos - Erlang gen_server eaddrnotavail after 16358 gen_tcp :connect calls,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32645444/