3

Erlang を学ぶために、.NET ベースの小さな Web サーバーを実装しようとしていますgen_tcp。残念ながら、私のコードは有線の動作を引き起こしているようです。問題を実証するために、問題を再現するのに十分な実装の最小化バージョンを添付しました。HTTP リクエストが何であれ、静的な 200 OK を配信しているだけです。

abWeb サーバーに対して (ループバック インターフェイスを使用して) (Apache HTTP サーバーのベンチマーク)を実行しようとすると、問題が発生します。同時リクエスト ( -c) がなければ、すべてが正常に実行されます。ただし、-c 8またはを使用すると、シェルに多数の行が表示されるため、一部のソケットでへ-c 16の呼び出しが失敗するようです。gen_tcp:accept/1request: closed

話全体をさらに奇妙にしているのは、さまざまなオペレーティング システムでさまざまな動作が見られることです。

  • OS X+Erlang/OTP 18:ab起動直後に「接続がピアによってリセットされました」と報告されます。
  • Debian+Erlang R15B01: 2 つを除くすべての HTTP リクエストが実行されているようです。しかし、その後、ab数秒間ハングし、「指定されたタイムアウトが期限切れになりました。合計 4998 の要求が完了しました」と報告ab-n 5000ます。同様に、15000 回のテストを実行すると 14998 が報告されます。

これは問題ではないようです。私は正直なところかなり迷っているので、助けていただければ幸いです!:) ありがとう!

server(Port) ->
    Opt = [list, {active, false}, {reuseaddr, true}],
    case gen_tcp:listen(Port, Opt) of
        {ok, Listen} ->
            handler(Listen),
            gen_tcp:close(Listen),
            ok;
        {error, Error} ->
            io:format("init: ~w~n", [Error])
    end.

handler(Listen) ->
    case gen_tcp:accept(Listen) of
        {ok, Client} ->
            request(Client),
            handler(Listen);
        {error, Error} ->
            io:format("request: ~w~n", [Error])
    end.

request(Client) ->
    Recv = gen_tcp:recv(Client, 0),
    case Recv of
        {ok, _} ->
            Response = reply(),
            gen_tcp:send(Client, Response);
        {error, Error} ->
            io:format("request: ~w~n", [Error])
    end,
    gen_tcp:close(Client).


reply() ->
    "HTTP/1.0 200 OK\r\n" ++
    "Content-Length: 7\r\n\r\n"
    "static\n".
4

1 に答える 1

4

同時に送信されるリクエストの数を増やすab -c Nと、サーバーに対して複数の TCP ソケットがすぐに開かれます。

デフォルトでは、gen_tcp:listen/2 で開かれたソケットは 5 つの未解決の接続要求のみをサポートします。{backlog, N} オプションを gen_tcp:listen/2 に指定して、未解決の接続要求の数を増やします。

OS Xでabを使用してコードをテストしたところ、「ピアによる接続のリセット」の問題が解決することがわかりました。

于 2015-09-11T02:09:36.677 に答える