2015-09-20 55 views
1

我爲一個簡單的服務器程序編寫了這個模塊,該程序接收請求並向客戶端發送響應。它工作正常但是,如果在客戶端連接時重新編譯此模塊,則客戶端斷開連接,如果我將客戶端重新連接到此服務器併發送請求,則沒有響應。有什麼想法?!爲什麼代碼版本控制器在erlang中不起作用?

這裏是我的模塊:

-module(controller). 
-export([start/1, loop/1, response/2]). 

-include_lib("types.hrl"). 

-define(END_CHAR, "$"). 


-spec start(Port) -> no_return() when 
    Port :: char(). 

-spec loop(Listen) -> no_return() when 
    Listen :: port(). 

-spec handler(Socket) -> no_return() when 
    Socket :: port(). 

-spec response(HandlerPID, Data) -> {send_msg, Msg} when 
    HandlerPID :: pid(), 
    Data :: string(), 
    Msg :: response(). 



start(Port) -> 
    {ok, Listen} = gen_tcp:listen(Port, [{active, once}]), 
    spawn(?MODULE, loop, [Listen]). 


loop(Listen) -> 
    {ok, Socket} = gen_tcp:accept(Listen), 
    spawn(?MODULE, loop, [Listen]), 
    handler(Socket). 



handler(Socket) -> 
    receive 
     {tcp, Socket, Data} -> 
      %io:format("recv ~p~n", [Data]), 
      spawn(?MODULE, response, [self(), Data]), 
      inet:setopts(Socket, [{active, once}]), 
      handler(Socket); 
     {tcp_closed, Socket} -> 
      %io:format("disconnected~n", []), 
      gen_tcp:close(Socket); 

     {send_msg, Msg} -> 
      gen_tcp:send(Socket, lists:flatten(io_lib:format("~p", [Msg])) ++ ?END_CHAR), 
      handler(Socket) 
    end. 


response(PID, Data) -> 
    [Req|Args] = string:tokens(Data, ?END_CHAR), 
    {ReqPID, ReqRef} = spawn_monitor(view, request, [list_to_atom(Req), self(), Args]), 
    receive 
     {'DOWN', ReqRef, process, ReqPID, {function_clause, _}} -> PID ! {send_msg, invalid_request}; 
     {'DOWN', ReqRef, process, ReqPID, {{case_clause, _}, _}} -> PID ! {send_msg, bad_args}; 
     {'DOWN', ReqRef, process, ReqPID, {{badmatch, _}, _}} -> PID ! {send_msg, bad_args}; 
     Resp -> PID ! {send_msg, Resp} 
    end. 

回答

0

{tcp_closed, Socket} -> 
     %io:format("disconnected~n", []), 
     gen_tcp:close(Socket); 
handler

。它不會再次調用handler,它只是返回,所以服務器進程停止。

你的loop函數名也是誤導,handler是實際循環。

+0

我收到請求或響應後再次致電hander! – Amin

+0

但是,當客戶端斷開時不行。正如你所說,「如果在客戶端連接時重新編譯這個模塊,**客戶端斷開連接**,並且如果我重新連接客戶端到這個服務器併發送請求,則沒有響應。你需要聽一個新的客戶。 –

+0

我試過了但不起作用。 – Amin

0

我建議看看Ranch - 一個用於TCP連接的套接字接收器池。

相關問題