2016-06-23 2 views
1

학습 목적으로 Erlang에 자체 웹 서버를 쓰고 있습니다. 현재 구현은 HTTP GET 요청을 구문 분석하고 이에 따라 응답 할 수 있습니다. 문제는 내 테스트 HTML 파일이 서버 프로세스를 종료 할 때까지 웹 브라우저에 표시되지 않는다는 것입니다. 메시지가 콘솔의 인쇄물에 의해 보내지는 것을 보았지만 웹 브라우저는 서버가 멈출 때까지로드를 유지합니다. 서버가 정지 된 것과 동일한 순간에 페이지가 표시됩니다. 왜 이런거야?서버가 멈춘 후에 웹 페이지 만 표시됨

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를 호출하여 생성 된 소켓을 수신합니다. 서버가 종료 된 후에 페이지가 표시되는 이유에 대한 지침이 있으면 감사하겠습니다.

+0

생각해보십시오.하지만 서버가 실행을 계속할 것으로 예상되는 곳을 차단해야하며 서버를 중지 할 때까지 해당 스택 실행을 완료하지 않습니다. – pay

+0

그럴 수도 있습니다. 나는 어디서부터 시작해야할지 모릅니다. 모든 것이 잘 작동하는 것 같고 "메시지를 보냈습니다!" 출력. 메시지가 그 후에 소켓에 ​​갇히지 않습니까? –

+0

또 다른 생각으로, 서버가 보내는 응답은 현재 어떤 헤더도 사용하지 않습니다. 요청 행과 본문 만 있습니다. 이로 인해 페이지가 표시되지 않을 수 있습니까? –

답변

4

문제는 응답 헤더에 Content-Length 데이터가 누락되었습니다.

데이터가 Content-Length이 아닌 경우 클라이언트는 연결 해제가 데이터 (본문) 세그먼트의 끝을 표시한다고 가정합니다.

서버는 연결을 닫지 않으며 시간 초과를 구현하지 않으므로 클라이언트는 더 많은 데이터를 기다리고 있습니다 (더 많은 데이터가 있다고 가정 함).

일단 연결이 닫히면 클라이언트는 이것을 본문 (데이터) 세그먼트의 끝으로 표시합니다.

Content-Length, ConnectionKeep-Alive에 대한 응답 헤더를 관리하고 시간 제한을 구현하는 것이 좋습니다.

specs 중 일부를 읽거나 위키 백과에서 HTTP Protocol 및 그 외의 정보를 headers으로 읽으면 프로토콜에 대해 자세히 학습하는 것이 좋습니다.

관련 문제