2

tcp_listener を gen_server() として実装しました。start_link(Port) という関数があり、そのポートで tcp_listener を作成します。ここで、stop() を使用して tcp_listener にリッスンを停止するように指示する方法を理解するのに苦労しています。このような関数を stop で呼び出してみました。

 stop() -> gen_server:cast(?MODULE, shutdown) 

terminate/2 関数で、リッスンしているソケットを閉じようとしましたが失敗しました。

 terminate(_Reason, State = #state{lsocket = LSocket}) ->
 gen_tcp:close(LSocket),
 NewState = State#state{lsocket = null},
 {ok, NewState}.

リッスンしているソケットを閉じると、生成した受け入れられた接続はどうなりますか。

ありがとうございました!

   start_link(Port) when is_integer(Port) ->
   State = #state{port = Port},
   gen_server:start_link({local, ?MODULE}, ?MODULE, State, []).

  init(State = #state{port = Port}) ->
  io:format("Supervisor started me and I am listening at ~p ~n", [Port]),
  case gen_tcp:listen(Port, ?TCP_OPTIONS) of
    {ok, LSocket} ->
     NewState = State#state{lsocket = LSocket},
     spawn(fun() -> accept(NewState) end),
     {ok, NewState};
    {error, Reason} ->
     {stop, Reason}
   end.

   accept(State = #state{lsocket = LSocket}) ->
   case gen_tcp:accept(LSocket) of
   {ok, Socket} ->
    Pid = spawn(fun() ->
    io:format("Connection accepted ~n"),
    loop(Socket)
              end),
    gen_tcp:controlling_process(Socket, Pid),
    accept(State);
    {error, closed} -> error
    end.

     loop(Socket) ->
    case gen_tcp:recv(Socket, 0) of
      {ok, Data} ->
       gen_tcp:send(Socket, Data),
     loop(Socket);
    {error, closed} ->
       ok
     end.
4

1 に答える 1

1

Learn You Some Erlang book のこの章を読むことをお勧めします。特に:

どちらのソケットも同じ方法でメッセージを送信でき、その後 で閉じることができますgen_tcp:close(Socket)。受け入れソケットを閉じると、そのソケットだけが閉じられ、リッスン ソケットを閉じると、関連する確立された受け入れソケットは閉じられませんが、現在実行中の受け入れ呼び出しは を返すことによって中断されることに注意してください{error, closed}

gen_tcp:close(Socket)したがって、すべてのソケットで呼び出すだけで済みます。

于 2016-04-05T23:29:42.853 に答える