[erlang-questions] Issue with my simple server, accept not accepting connections
Pablo Polvorin
pablo.polvorin@REDACTED
Sat Mar 8 16:54:28 CET 2008
Try to establish a tcp connection *really* quickly after starting the
server and see what happens.. you will be able to connect (and then
crash with {undef,[{client_handler,start_link,[]).
I guess the reason you can't connect to the server is that you are
hitting a timeout inside your gen_server: handle_call/3
implementation (witch doesn't return in the expected time).
Anyway, there is an introductory TCP server example <chargen.erl>, at
http://www.erlang.org/examples/klacke_examples/index.html
you could use that as a starting point for simplifying your code.
cheers,
pablo.
2008/3/7, bbrown <bbrown@REDACTED>:
> Hello, this kind of a long post (lot of code) and maybe I need to simplify my
> code but I am writing a simple tcp server and maybe you see something that is
> totally off. I have one application module and a server module (a type of
> middle-man) and then the client-handler module.
>
> Everything gets called correctly, but I can't connect to the server. I get a
> connection refused for example if
>
> This is my server library as a gen_server module.
>
> The key code is here and my issue. When I try to connect to the server, it
> looks like it never calls the code after "accept".
>
> I get to this line:
> io:format("trace: lib:handle_call accept_clients. [~p]~n", [AppHandler])
>
> But I don't get to this line after the accept call:
>
> io:format("trace: [!!] lib:handle_call client-socket: [~p]~n", [ClientSock]),
>
> -----------------
>
> io:format("trace: lib:handle_call accept_clients. [~p]~n", [AppHandler]),
> ClientSock = server_accept(ServSock),
> io:format("trace: [!!] lib:handle_call client-socket: [~p]~n", [ClientSock]),
>
>
> -----------------
>
> server_accept(ServSock) ->
> { ok, ClientSock } = gen_tcp:accept(ServSock),
> ClientSock.
> -----------------
> handle_call(irc_server_bind, _From,
> #server_state{client=Client } = State) ->
> Port = Client#irc_server_info.port,
> io:format("trace: lib:handle_call:bind Port:<~p>~n", [Port]),
> {ok, ServSock} = server_bind(Port),
> {reply, ok, State#server_state{serv_sock=ServSock, state=connecting}};
> handle_call(irc_accept_clients, _From,
> #server_state{serv_sock=ServSock, app_handler=AppHandler } = State) ->
> io:format("trace: lib:handle_call accept_clients. [~p]~n", [AppHandler]),
> ClientSock = server_accept(ServSock),
> io:format("trace: [!!] lib:handle_call client-socket: [~p]~n", [ClientSock]),
> { ok, ClientServ } = client_handler:start_link(),
> % Assign a new controlling process.
> gen_tcp:controlling_process(ClientSock, ClientServ),
> inet:setopts(ClientSock, [{packet, 0}, binary,
> {nodelay, true},{active, false}]),
> % Invoke gen_server:cast to handle the socket
> {reply, ok, State};
> handle_call(get_cur_state, _From, #server_state{} = State) ->
> % Generic method to get the current state.
> io:format("trace: lib:handle_call:get_cur_state~n"),
> {reply, {ok, State}, State}.
>
> terminate(_Reason, #server_state{client=Client}) ->
> io:format("trace: lib:terminate reason:[~p]~n", [_Reason]),
> ok;
> terminate(shutdown, #server_state{client=Client}) ->
> io:format("trace: lib:terminate.shutdown~n"),
> ok.
>
> handle_info(server_timeout, #server_state{client=Client} = State) ->
> io:format("trace: lib:handle_info.server_timeout"),
> %{noreply, State#server_state{state=timeout, connection_timeout=undefined}}.
> {noreply, State}.
>
> server_listen(ServLib) ->
> io:format("trace: lib:server listen [~p]~n", [ServLib]),
> % Synchronous gen_server call
> gen_server:call(ServLib, irc_server_bind).
>
> %% Accept call and then cast to handle new client
> server_accept_call(ServLib) ->
> io:format("trace: lib:server accept new client~n"),
> gen_server:call(ServLib, irc_accept_clients).
>
> get_cur_state(ServLib) ->
> io:format("trace: lib:get_cur_state: pid:[~p] ~n", [ServLib]),
> % Return: {ok, State}
> gen_server:call(ServLib, get_cur_state).
>
> server_bind(Port) ->
> io:format("trace: attempting to bind server... [~p]~n", [Port]),
> gen_tcp:listen(Port, [binary, {packet, 0},
> {active, false}]).
>
> server_accept(ServSock) ->
> { ok, ClientSock } = gen_tcp:accept(ServSock),
> ClientSock.
>
> connection_timeout() ->
> % Time out delay of 1 minute
> 600000.
> ----------------
>
> start_test_serv() ->
> io:format("Running functional test~n"),
> % Ensure that the app_handler is associcated with this app process
> Client = #irc_server_info{app_handler=self()},
> Pid = start(Client),
> io:format("trace: <after start> start server, handler:~p ~n", [Pid]),
> % Wait a couple of seconds and then send messages to wait_for_clients.
> timer:sleep(500),
> init_accept_clients(),
> % Pass the pid of the server handler process.
> wait_for_clients(Pid),
> io:format("Done~n").
>
> wait_for_clients(ServHandler) ->
> io:format("trace: app: wait_for_clients~n"),
> receive
> Anything ->
> % Application process is ready to accept new clients
> io:format("trace: app: wait_messages:accept <incoming>~n"),
> accept_clients(ServHandler),
> wait_for_clients(ServHandler)
> after connection_timeout() + 20000 ->
> io:format("INFO: Timed out~n")
> end.
> -----------------
>
> Here is my server handler code.
>
> server_handler(Client) ->
> ServStart = server_lib:start_link(Client),
> case ServStart of
> { ok, P } ->
> io:format("trace: app:server pid/lib [~p]~n", [P]),
> server_lib:server_listen(P),
> State = server_lib:get_cur_state(P),
> % io:format("trace: app:server state [~p]~n", [State]),
> server_handler(#serv_handler_info{lib_handler=P}, idle)
> end.
>
> server_handler(ServClient, idle) ->
> ServLib = ServClient#serv_handler_info.lib_handler,
> io:format("trace: [!] at server_handler.idle [~p]~n", [ServLib]),
> receive
> { ready_accept } ->
> % Application process is ready to accept new clients
> io:format("trace: app: wait_messages:accept <incoming>~n"),
> % Launch initial accept clients block
> AcceptCall = server_lib:server_accept_call(ServLib),
> io:format("!!!-->~p~n", [AcceptCall]),
> case AcceptCall of
> { ok, State } ->
> io:format("poo~n")
> end,
> server_handler(ServClient, idle);
> Error ->
> io:format("trace: [!] app:error.proceeed<idle>: ~p~n", [Error]),
> server_handler(ServClient, idle)
> after connection_timeout() ->
> io:format("trace: [!] at server_handler. TIMEOUT ~n"),
> server_handler(ServClient, idle)
> end.
>
> accept_clients(ServHandler) ->
> % Start waiting accept new client connections.
> ServHandler ! {ready_accept}.
>
> init_accept_clients() ->
> % Start waiting accept new client connections.
> self() ! {init_accept}.
>
>
> -----------------
>
> And if you are really curious; here is the source in subversion:
>
> http://openbotlist.googlecode.com/svn/trunk/botlistprojects/laughingman/test/ircserver/src/
>
> --
> Berlin Brown
> email: berlin-dot-brown-AT-gmail-dot-com
> http://botspiritcompany.com/botlist/
>
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://www.erlang.org/mailman/listinfo/erlang-questions
>
--
--
pablo
http://ppolv.wordpress.com
----
More information about the erlang-questions
mailing list