求教,erlang 的 gen_tcp 如何处理列表?

发布于 2021-11-22 14:20:00 字数 4067 浏览 756 评论 1

环境:  c/s 模式,都是linux 服务器

目的: 实现, c端发命令, 到S端执行,然后把  S 端的执行结果返回给 C端

问题: 服务端的 os:cmd() 用来执行 客户端提交的命令, 但在处理 os:cmd("ls") 和 os:cmd("ls -la") 时, 前者返回的是 <<结果字符串>>, 后者返回的是 [结果binary],在此情况下, 如何处理, <<>> 和 [] 的收发问题?


代码:

服务端 :


-module(dty_server).
-compile(export_all).

-define(PORT, 8046).
-record(server, {lsocket, slog}).

start() -> start(?PORT).
start(Port) -> 
    {ok, Lsocket} = gen_tcp:listen(Port, [binary, {active, false}, {packet, 0}]),
    {ok, Log} = file:open("s.log", [write, binary, append]),
    wait_connect(#server{lsocket = Lsocket, slog = Log}).

wait_connect(#server{lsocket = Lsocket, slog = Log} = Server) ->
    {ok, Socket} = gen_tcp:accept(Lsocket),
    gen_tcp:controlling_process(Socket, spawn(?MODULE, get_request, [Socket, Log])),
    wait_connect(Server).

get_request(Socket, Log) ->
    case gen_tcp:recv(Socket, 0) of 
        {ok, Binary} -> 
            file:write(Log, io_lib:format("nGot: ~p~n", [Binary])),
            process_request(Socket, Binary, Log);
        {error, closed} ->
            file:write(Log, "error, closed...n")
    end.

process_request(Socket, Data, Log) ->
    file:write(Log, io_lib:format("[~p] CMD:  ~p~n", [[date(), time()], Data])), 
    Res = os:cmd(Data),
    file:write(Log, io_lib:format("Result: ~p~n", [Res])),
    send(Socket, list_to_binary(Res)),
    gen_tcp:close(Socket).

send(Socket, <<H:100/binary, T/binary>>) ->
    gen_tcp:send(Socket, H),
    io:format("send: ~p~n", [H]),
    send(Socket, T);
send(Socket, <<T>>) -> 
    io:format("send: ~p~n", [T]),
    gen_tcp:send(Socket, T).


客户端:

-module(dty_client).
-compile(export_all).

-define(PORT, 9046).
-define(HOST, {192, 168, 1, 119}).

start() -> 
    io:format("the commands can be used: ~n", []),
    help(),
    case init:get_argument(cmd) of
        {ok, [[Arg]]} ->
            Cmds = get_cmds(),
            case lists:member(Arg, Cmds) of
                true ->
                    send(Arg);
                false ->
                    io:format("command ~p not exists, start executing it on remote server~n", [Arg]),
                    send(Arg)
            end;
        error ->
            send("ls /"),
            io:format("no cmd parameter, please add the parameter cmd!~n", [])
    end.

send(Cmd) -> 
    {ok, Socket} = connect(),
    io:format("sending data: ~p~n", [Cmd]),
    send(Socket, Cmd),
    client_recv(Socket, []).

send(Socket, <<Chunk:100/binary, Rest/binary>>) ->
    gen_tcp:send(Socket, Chunk),
    send(Socket, Rest);
send(Socket, Rest) -> gen_tcp:send(Socket, Rest).

client_recv(Socket, BinaryList) ->
    case gen_tcp:recv(Socket, 0) of 
        {ok, Binary} ->
            client_recv(Socket, [Binary | BinaryList]);
        {error, closed} ->
            print_result(lists:reverse(BinaryList));
        {tcp_closed, Reason} ->
            io:format("TCP_CLOSED: ~p~n", [Reason]),
            print_result(lists:reverse(BinaryList))
    end.

print_result(Result) ->
    Lines = re:split(Result, "n"),
    io:format("~p~n", [Lines]),
    print(Lines).
    
print([]) -> io:format("~n", []);
print([H | T]) -> io:format("~ts~n", [H]), print(T).

help() -> io:format("cmds: ~p~n", [get_cmds()]).

get_cmds() -> ["svn_yy_api", "svn_yy_admin", "svn_smy_api", "svn_smy_admin", "svn_ddz_api", "svn_ddz_admin", "svn_sys", "svn_www"].
    
connect() -> connect(?HOST, ?PORT).
connect(Host, Port) -> 
    {ok, Socket} = gen_tcp:connect(Host, Port, [binary, {packet, 0}, {active, false}]),
    io:format("connecting ~p : ~p ...... ok.~n", [Host, Port]),
    {ok, Socket}.



求教,谢谢!


如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

夜血缘 2021-11-25 07:37:32

unicode:characters_to_binary() 解决!!!

谢谢 中国erlang俱乐部群的 人之初!!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文