2
我正在Erlang編寫一個服務器,並且想要打開大量的連接。問題是我在16358 gen_tcp:connect/3
調用後收到{error,eaddrnotavail}。正如你在下面看到的,服務器非常簡單。Erlang gen_server eaddrnotavail在16358之後gen_tcp:連接調用
我修改了我的MacOS約塞米蒂限制; 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).
是的,就是這樣。現在我將第一個設置爲1025,最後設置爲65535,我可以打開64510個連接。我現在正在尋找一種更加開放的方式,如果您知道某種方式,請告訴我......感謝您的時間 –
這裏的限制實際上是TCP協議。當你查看tcp頭時,你會看到端口號是16位整數,所以你不能在每個IP上產生超過65535個端口,但是當然你可以添加另一個網絡接口一個不同的IP。我不知道如何在OSX上添加另一個接口/子接口。有時添加另一臺機器會更容易。如果你設法添加一個額外的接口,你可以使用{ip,ip_address()}選項指定在'gen_tcp:connect'選項中使用哪一個接口。 –
確實;我將我的開發人員移動到了Oracle Linux 7上,即使我有參數,我也可以打開超過100K的連接:net.inet.ip.portrange.first:49152 net.inet.ip.portrange.last:65535 OSX很奇怪> 。>無論如何,謝謝你的時間 –