Hi all,
Very new to Erlang, coming from C/C++/Java. Been playing with code and have myself narrowed to a point where a second of guidance might save me a half a day. So what I have is a little telnet client which I'm intending to connect to a freeswitch esl port and let me issue commands to the port as I would in fs_cli. (I guess the main thing is…I'm trying to talk to a port that I should be able to communicate via telnet). The erlang app fails while a Linux telnet is working great. I'm sure the issue is simple and subtle; any help appreciated!
So, here's how the session goes using Linux telnet:
$>telnet localhost 8021
Trying localhost...
Connected to localhost.
Escape character is '^]'.
Content-Type: auth/request
auth password<ENTER>
<ENTER>
Content-Type: command/reply
Reply-Text: +OK accepted
log 1<ENTER>
<ENTER>
Content-Type: command/reply
Reply-Text: +OK log level 1 [1]
…Okay, here's my telnet client code:
-module(getty).
-export([s/0]).
%-define(LISTEN_PORT, 9000).
%-define(TCP_OPTS, [binary, {packet, raw}, {nodelay, true}, {reuseaddr, true}, {active, once}]).
s() ->
case gen_tcp:connect( "localhost", 8021,[{active,false},{packet,2}]) of
{ok,Sock} ->
io:format("~p Connected to localhost 8021.~n", [erlang:localtime()] ),
main_loop( Sock );
Error ->
io:format("Error: ~p~n", [Error])
end.
main_loop( Sock ) ->
Command = get_user_input( "Command> " ),
spawn(fun() -> ex_cmd( Sock, Command ) end),
main_loop( Sock ).
ex_cmd(Sock, Command) ->
B = gen_tcp:recv( Sock, 0 ),
io:format( "Response: ~p~n", [B] ),
gen_tcp:send( Sock, Command ),
A = gen_tcp:recv( Sock, 0 ),
%gen_tcp:close( Sock ),
io:format( "Response: ~p~n", [A] ).
get_user_input( Prompt ) ->
A1 = string:concat(
string:strip( % remove spaces from front and back
string:strip( % remove line-feed from the end
io:get_line( Prompt ), right, $\n)), "\r\n\r\n" ),
io:format( "Command is: ~p~n", [A1] ),
A1.
…here's a run of using the erlang client:
$>erl
Erlang R15B01 (erts-5.9.1) [source] [smp:8:8] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9.1 (abort with ^G)
1> c(getty).
{ok,getty}
2> getty:s().
{{2012,7,12},{10,15,0}} Connected to localhost 8021.
Command> auth password
Command is: "auth password\r\n\r\n"
Response: {error,closed}
Response: {error,closed}
Command>
Any clues on the different result using the erlang client? TIA!
By using {packet,2}, you're claiming that packets will be sent with a 2-byte header declaring the size of the packet, and that you're expecting the server to send such headers as well. Telnet does not do this, so if you're trying to emulate a telnet client, don't specify a packet mode of 2. Instead, use 0 or raw for the packet type to specify no header. I believe that leaving off the packet option defaults to no header as well.