[erlang-questions] Issue with my simple server, accept not accepting connections
bbrown
bbrown@REDACTED
Fri Mar 7 18:44:24 CET 2008
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/
More information about the erlang-questions
mailing list