如何在erlang中停止作为gen_server实现的tcp_listener

时间:2016-04-05 22:12:01

标签: erlang otp gen-server gen-tcp

我将tcp_listener实现为gen_server()。我有一个名为start_link(Port)的函数在该端口创建一个tcp_listener。现在,我无法理解如何告诉tcp_listener停止通过stop()进行监听。 我尝试用stop来调用这样的函数。

 stop() -> gen_server:cast(?MODULE, shutdown) 
终止/ 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.

1 个答案:

答案 0 :(得分:1)

我建议您查看this chapter in the Learn You Some Erlang book,特别是:

  

两个套接字都可以以相同的方式发送消息,然后可以使用gen_tcp:close(Socket)关闭。请注意,关闭接受套接字将仅关闭该套接字,关闭侦听套接字将不会关闭任何相关和已建立的接受套接字,但会通过返回{error, closed}来中断当前正在运行的接受调用。

所以它应该只是在所有套接字上调用gen_tcp:close(Socket)