求教,erlang 的 gen_tcp 如何处理列表?
环境: 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
unicode:characters_to_binary() 解决!!!
谢谢 中国erlang俱乐部群的 人之初!!