2016-06-23 10 views
1

私は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. 

上記は私が書いたコードの一部です。私は構文解析を残しましたが、その部分は機能します。リスナー/ 1は、オプションリスト{active、false}でgen_tcp:listen/2を呼び出して作成したソケットを受け取ります。サーバーがシャットダウンされた後にページが表示される理由についてのガイダンスは高く評価されます。

+0

あなたのサーバーは、実行を続行すると予想されるどこかでブロックされている必要があり、サーバーを停止するまでそのスタックの実行を終了しません。 – pay

+0

そうかもしれないが、私はどこから見始めるのか分かりません。すべてが正常に動作しているようだと私は "メッセージを送った!"プリントアウト。その後、メッセージはソケットに詰まっていますか? –

+0

また別の考えでは、サーバーが送信する応答は現在、ヘッダーを使用していません。要求行と本文だけがあります。これによりページが表示されないことがありますか? –

答えて

4

問題は、応答ヘッダーにContent-Lengthのデータがないことです。

データはContent-Lengthのデータがないと、切断によってデータ(本文)セグメントの終わりがマークされるとみなされます。

サーバーは決して接続をクローズしません(タイムアウトも実装しません)ので、クライアントはより多くのデータを待っています(それ以上のデータがあると仮定します)。

接続が閉じられると、クライアントはこれを本文(データ)セグメントの末尾としてマークします。

Content-Length,ConnectionおよびKeep-Aliveの応答ヘッダーを管理するだけでなく、タイムアウトを実装することを検討する必要があります。

specsを読んだり、ウィキペディアでHTTP Protocolを読んだり、headersについて読んだりすることで、プロトコルの詳細を学ぶことを検討してください。

関連する問題