Note that there are some explanatory texts on larger screens.

plurals
  1. POgen_server closing listening socket
    primarykey
    data
    text
    <p>What I'm trying to do is have a gen_server process accept a new client and immediately spawn a new child to handle the next one. The issue that I'm seeing is that when the socket is finished and consequentially terminates, it also closes the listening socket and I can't figure out why, even though it no longer references it.</p> <p>Any idea what I am doing wrong?</p> <p>gen_server:</p> <pre><code>-module(simple_tcp). -behaviour(gen_server). %% API -export([start_link/1, stop/0, start/0, start/1]). %% gen-server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). -define(SERVER, ?MODULE). -define(DEFAULT_PORT, 1055). -record(state, {port, lsock}). start_link({port, Port}) -&gt; gen_server:start_link(?MODULE, [{port, Port}], []); start_link({socket, Socket}) -&gt; gen_server:start_link(?MODULE, [{socket, Socket}], []). start({port, Port}) -&gt; simple_tcp_sup:start_child({port, Port}); start({socket, Socket}) -&gt; simple_tcp_sup:start_child({socket, Socket}). start() -&gt; start({port, ?DEFAULT_PORT}). stop() -&gt; gen_server:cast(?SERVER, stop). % Callback functions init([{port, Port}]) -&gt; {ok, LSock} = gen_tcp:listen(Port, [{active, true},{reuseaddr, true}]), init([{socket, LSock}]); init([{socket, Socket}]) -&gt; io:fwrite("Starting server with socket: ~p~n", [self()]), {ok, Port} = inet:port(Socket), {ok, #state{port=Port, lsock=Socket}, 0}. handle_call(_Msg, _From, State) -&gt; {noreply, State}. handle_cast(stop, State) -&gt; {stop, ok, State}. handle_info({tcp, Socket, RawData}, State) -&gt; gen_tcp:send(Socket, io_lib:fwrite("Received raw data: ~p~n", [RawData])), {noreply, State}; handle_info({tcp_error, _Socket, Reason}, State) -&gt; io:fwrite("Error: ~p~n", [Reason]), {stop, normal, State}; handle_info(timeout, #state{lsock = LSock} = State) -&gt; case gen_tcp:accept(LSock) of {ok, Sock} -&gt; io:fwrite("Accepting connection...~p~n", [self()]), start({socket, LSock}), {noreply, #state{lsock=Sock}}; {error, Reason} -&gt; io:fwrite("Error: ~p, ~p~n", [Reason, self()]), {stop, normal, State} end; handle_info({tcp_closed, _Port}, State) -&gt; io:fwrite("Socket closed: ~p~n", [self()]), simple_tcp_sup:kill_child(self()), {stop, normal, State}. terminate(_Reason, _State) -&gt; io:fwrite("Shutting down server: ~p~n", [self()]), ok. code_change(_OldVsn, State, _Extra) -&gt; {ok, State}. </code></pre> <p>supervisor:</p> <pre><code>-module(simple_tcp_sup). -behaviour(supervisor). -export([start_link/0, start_child/1 ]). -export([init/1]). -define(SERVER, ?MODULE). start_link() -&gt; supervisor:start_link({local, ?SERVER}, ?MODULE, []). start_child({socket, Socket}) -&gt; io:fwrite("Spawning child with socket...~n"), supervisor:start_child(?SERVER, [{socket, Socket}]); start_child({port, Port}) -&gt; io:fwrite("Spawning child with port...~n"), supervisor:start_child(?SERVER, [{port, Port}]). init([]) -&gt; Element = {simple_tcp, {simple_tcp, start_link, []}, temporary, brutal_kill, worker, [simple_tcp]}, Children = [Element], RestartStrategy = {simple_one_for_one, 0, 1}, {ok, {RestartStrategy, Children}}. </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload