1

大家好,

Erlang 非常新,来自 C/C++/Java。一直在玩代码,让自己缩小到一个点,一秒钟的指导可能会节省我半天的时间。所以我有一个小 telnet 客户端,我打算连接到一个 freeswitch esl 端口,让我像在 fs_cli 中一样向该端口发出命令。(我想主要是......我正在尝试与我应该能够通过 telnet 通信的端口交谈)。当 Linux telnet 运行良好时,erlang 应用程序失败。我敢肯定这个问题很简单而且很微妙。任何帮助表示赞赏!

因此,这里是使用 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]   

…好的,这是我的 telnet 客户端代码:

-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.

...这是使用 erlang 客户端的运行:

$>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>   

关于使用 erlang 客户端的不同结果的任何线索?蒂亚!

4

1 回答 1

4

通过使用 {packet,2},您声称数据包将发送一个 2 字节的标头来声明数据包的大小,并且您希望服务器也发送此类标头。Telnet 不这样做,因此如果您尝试模拟 telnet 客户端,请不要将数据包模式指定为 2。相反,使用 0 或 raw 作为数据包类型以指定无标头。我相信离开数据包选项默认也没有标头。

于 2012-07-12T15:36:07.840 回答