2016-04-08 3 views
0

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. 
+3

_Elseの結果をクライアントに出力して、サーバーへの接続に失敗した理由を知ることができます。あなたの投稿をより簡単に読むために再フォーマットしました。 クライアントが接続に成功すると、クライアントはループせず、プロセスはすぐに終了し、ソケットを閉じているように見えます。 – Pascal

+2

デフォルト値は5ですので、TCPのリスンバックログを確認する必要があります。 'B 'が整数である' {バックログ、B} 'オプションを使ってリスンコールに設定できます。ああ、また、 'gen_tcp'は動作ではなく、単なるモジュールです。 –

答えて

1

それが真実であること、単一のプロセスのみ可能gen_tcp:accept/1私はそれがだとはわからないものの、非常に高速あなたが走っているボトルネック。

あなたは、カウボーイウェブサーバーのTCPライブラリであるRanchに興味があるかもしれません。このマニュアルには、複数のアクセプタの使用について語るsection on internal featuresが含まれています。

あなたの場合、より多くのデバッグ出力を自分自身で生成するようにしてください。クライアントが接続に失敗したときにエラーを表示するのは良いスタートです.TCPクライアントが接続に失敗する理由はたくさんあります。

関連する問題