erlang gen_tcp:使用超级用户时连接将关闭

8aqjt8rx  于 2022-12-08  发布在  Erlang
关注(0)|答案(1)|浏览(169)

I have a simple gen_server which connects to a tcp port, when I run gen_server directly:
erl -noshell -s ttest start
it works fine, But when I run:
erl -noshell -s tt_sup start_link
the connection will be closed instantly, It will work if I unlink the supervisor:
erl -noshell -s tt_sup start_shell
How could I run my simple gen_tcp:connect (gen_server) with supervisor ?
Supervisor :

-module(tt_sup).
-behaviour(supervisor).
-export([init/1, start_link/0, start_shell/0]).

start_link() ->
    io:format("Supervisor started with PID~p~n", [self()]),
    {ok, Pid} = supervisor:start_link(tt_sup, []),
    io:format("Supervisor PID=~p~n", [Pid]),
    {ok, Pid}.

start_shell() ->
    io:format("Supervisor started with PID~p~n", [self()]),
    {ok, Pid} = supervisor:start_link(tt_sup, []),
    io:format("Supervisor PID=~p~n", [Pid]),
    unlink(Pid),
    {ok, Pid}.

init(_Args) ->
    SupFlags = #{strategy => one_for_one},
    Child = [#{id => ttest, start => {ttest, start, []},
               restart => permanent, shutdown => brutal_kill,
               type => worker, modules => [ttest]}],
    {ok, {SupFlags, Child}}.

gen_server:

-module(ttest).
-export([start/0,init/1,handle_cast/2,handle_call/3,handle_info/2,terminate/2,connect/1]).
-behaviour(gen_server).


start() ->

       io:format("gen_server start id is ~p~n",[self()]),
       {ok,Pid} = gen_server:start_link({local,ttest},ttest,[],[]),
       io:format("gen_server id is ~p~n",[Pid]),
       connect(Pid),
       {ok,Pid}.


init(_Args) ->
        io:format("init id is ~p~n",[self()]),
        {ok,[]}.       
handle_call({tcp,Socket,Bin},_From,States) ->
        {reply,States,States}.
handle_info({tcp,Socket,Bin},States) ->
        io:format("got info msg"),
        {noreply,States}.

handle_cast({send,Msg},States) ->
        {reply,States}.

connect(I) ->
    io:format("connect id is ~p~n",[self()]),
    {ok,Socket} =gen_tcp:connect("localhost",6000,[binary,{active,true}]),
    gen_tcp:controlling_process(Socket,I).


terminate(shutdown, State) ->
    io:format("terminating"),
    ok.
toiithl6

toiithl61#

The process that runs the -s exits with normal when it has no more code to execute. The supervisor receives that signal and since it's from its parent, it exits (regardless of it being normal ), as explained in gen_server:terminate/2 ( supervisor s are gen_server s with trap_exit active):
Even if the gen_server process is not part of a supervision tree, this function is called if it receives an 'EXIT' message from its parent. Reason is the same as in the 'EXIT' message.
I haven't tested your code, but if you add a process_flag(trap_exit, true) to your gen_server , you'll surely replicate this behaviour.

相关问题