gen_tcp
の動作を使用すると面白い問題が見つかりました。私はサーバーとクライアントを持っています。サーバーは接続を受け入れ、クライアントはすべてリスニングサーバーに接続しようとする多くのプロセスを作成します。gen_tcp使用時のソケット受け入れ率
ソケットを同時に接続しようとする多くのプロセスを起動するクライアントを起動しようとすると、多くの場合失敗します。しかし、もし私がtimer:sleep(x)
を置くと、すべてのソケットが受け入れられています。
これは、gen_tcp:accept()
に何らかの接続要求を受け入れることができるという制限があることを意味しますか?サーバとクライアントのための
コードは次のとおりです。
accept(State = #state{lsocket = LSocket, num = Num}) ->
case gen_tcp:accept(LSocket) of
{ok, Socket} ->
io:format("Accepted ~p ~n", [Num]),
{sockets, List} = hd(ets:lookup(csockets, sockets)),
NewList = [Socket | List],
ets:insert(csockets, {sockets, NewList}),
Pid = spawn(fun() -> loop(Socket) end),
gen_tcp:controlling_process(Socket, Pid),
accept(State#state{num = Num + 1});
{error, closed} -> State
end.
loop(Socket) ->
case gen_tcp:recv(Socket, 0) of
{ok, Data} ->
gen_tcp:send(Socket, Data),
loop(Socket);
{error, closed} ->
io:format(" CLOSED ~n"),
ok
end.
クライアント:
send(State = #state{low = Low, high = Low}) ->
State;
send(State = #state{low = Low}) ->
N = Low rem 10,
Dest = lists:nth(N + 1, State#state.dest),
spawn(?MODULE, loop, [Dest, Low]),
%%timer:sleep(1),
NewState = State#state{low = Low + 1},
send(NewState).
loop({IP, Port}, Low) ->
case gen_tcp:connect(IP, Port, [binary]) of
{ok, Socket} ->
io:format("~p Connected ~n", [Low]),
gen_tcp:send(Socket, "Hi"),
receive
{tcp, RecPort, Data} ->
io:format("I have received ~p on port ~p ~p ~n", [Data, RecPort, Low])
end;
_Else ->
io:format("The connection failed ~n"),
loop({IP, Port}, Low)
end.
_Elseの結果をクライアントに出力して、サーバーへの接続に失敗した理由を知ることができます。あなたの投稿をより簡単に読むために再フォーマットしました。 クライアントが接続に成功すると、クライアントはループせず、プロセスはすぐに終了し、ソケットを閉じているように見えます。 – Pascal
デフォルト値は5ですので、TCPのリスンバックログを確認する必要があります。 'B 'が整数である' {バックログ、B} 'オプションを使ってリスンコールに設定できます。ああ、また、 'gen_tcp'は動作ではなく、単なるモジュールです。 –