【发布时间】:2016-07-26 01:56:38
【问题描述】:
我将 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.
【问题讨论】:
-
您不会产生连接,只会产生一个进程。如果关闭套接字,所有连接都将被丢弃。您实际上是否在生成任何进程?
-
是的,我实际上是在生成进程。如果我接受连接,我将产生一个新进程。因此,稍后即使我关闭了监听套接字,我也可以在发送和接收消息时使用已接受的套接字(在我的情况下为 echo_server)。请参考代码,现已编辑。
标签: erlang erlang-otp gen-server gen-tcp