Erlang TCP套接字关闭



为了学习Erlang,我正在尝试实现一个基于gen_tcp的小型web服务器。不幸的是,我的代码似乎触发了一些奇怪的行为。为了演示这个问题,我附上了一个最小化的实现版本,足以重现这个问题。不管HTTP请求是什么,它只是传递一个静态的200ok。

问题出现时,我试图运行ab (Apache HTTP服务器基准测试)对我的web服务器(使用环回接口)。没有任何并发请求(-c),一切都运行良好。然而,如果我使用-c 8-c 16,对gen_tcp:accept/1的调用似乎在一些套接字上失败,因为我在shell中看到许多request: closed行。

更奇怪的是,我在不同的操作系统上看到了不同的行为:

  • OS X+Erlang/OTP 18: ab几乎在启动后立即报告"连接重置"
  • Debian+Erlang R15B01:除了两个HTTP请求外,所有请求似乎都通过了。但是,当我用-n 5000运行ab时,ab挂起几秒钟并报告"指定的超时已过期,总共完成4998个请求"。类似地,当我运行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 OKrn" ++
    "Content-Length: 7rnrn"
    "staticn".

当你增加ab -c N并发请求的数量时,它会立即打开多个TCP套接字到服务器。

默认情况下,使用gen_tcp:listen/2打开的套接字将只支持5个未完成的连接请求。使用gen_tcp:listen/2选项{backlog, N}增加未完成连接请求的数量。

我用ab在OS X上测试了你的代码,看到这解决了"连接重置"的问题。

最新更新