网页仅在服务器停止后显示

Web page only displaying after server stopped

出于学习目的,我正在用 Erlang 编写一个自制的 Web 服务器。当前的实现可以解析 HTTP GET 请求并做出相应的响应。问题是在我关闭服务器进程之前,我的测试 HTML 文件不会显示在 Web 浏览器中。我看到控制台中的打印正在发送消息,但 Web 浏览器一直在加载,直到服务器停止。服务器停止的同时显示页面。这是为什么?

listener(Listen) ->
  case gen_tcp:accept(Listen) of
    {ok, Client} ->
      case gen_tcp:recv(Client, 0) of
        {ok, Request} ->
          workers:worker({Client, Request});
        {error, closed} ->
          io:format("Socket closed.~n");
        {error, _Reason} ->
          io:format("Error: ~w~n", [_Reason])
      end,
      listener(Listen);
    {error, Error} ->
      io:format("Error ~w~n", [Error]),
      error
  end.

worker({Client, Request}) ->
  {Request_line, Headers, Body} = http_parse:parse_request(Request),
  Response = http_parse:create_response({Request_line, Headers, Body}),
  case gen_tcp:send(Client, Response) of
     ok ->
      io:format("Message sent!~n");
    {error, Reason} ->
      io:format("Could not send packet: ~w~n", [Reason])
  end.

上面是我写的一些代码。我已经离开了解析,但那部分有效。 listener/1 接收通过使用选项列表 {active, false} 调用 gen_tcp:listen/2 创建的套接字。感谢任何关于为什么页面仅在服务器关闭后显示的指导。

问题是响应 header 缺少 Content-Length 数据。

没有 Content-Length 数据,客户端假定断开连接将标记数据 (body) 段的结束。

您的服务器永远不会关闭连接(也不会实现超时),因此客户端一直在等待更多数据(它假设有更多数据正在传输中)。

连接关闭后,客户端会将此标记为 body(数据)段的结尾。

您应该考虑实现超时并管理 Content-LengthConnectionKeep-Alive 的响应 headers。

考虑通过阅读一些 specs or reading in Wikipedia about the HTTP Protocol and it's headers.

来了解更多关于该协议的信息