我正在使用dbg:p(client, r)
运行以下代码:
-module(client).
-export([start/0, start/2, send/1, net_client/1]).
start() ->
start("localhost", 7000).
start(Host, Port) ->
io:format("Client connecting to ~p:~p.~n", [Host, Port]),
register(ui, spawn(fun() -> gui_control([]) end)),
case gen_tcp:connect(Host, Port, [binary, {packet, 0}]) of
{ok, Socket} ->
Pid = spawn(client, net_client, [Socket]),
register(client, Pid),
gen_tcp:controlling_process(Socket, Pid);
Error ->
io:format("Error connecting to server: ~p~n", [Error]),
erlang:error("Could not connect to server.")
end,
ok.
send(Msg) ->
client!{send, Msg}.
%% Forwards messages to either the GUI controller or the server.
net_client(Socket) ->
receive
{tcp, Socket, Message} ->
Msg = binary_to_term(Message),
io:format("Received TCP message on ~p: ~p~n", [Socket, Msg]),
ui!{server, Msg};
{send, Message} ->
io:format("Sending ~p.~n", [Message]),
gen_tcp:send(Socket, term_to_binary(Message));
close ->
gen_tcp:close(Socket),
exit(normal);
{tcp_closed, Socket} ->
io:format("Server terminated connection.~n"),
exit(normal); %% Reconnect?
timeout -> %% This
io:format("Timed out?~n");
{inet_reply, Socket, Message} -> %% and this never happen.
io:format("inet_reply: ~p~n", Message);
Error ->
io:format("Net client got bad message: ~p.~n", [Error])
after 10000 ->
refresh %% gen_tcp:send(Socket, term_to_binary(keepalive))
end,
?MODULE:net_client(Socket).
gui_control(Data) ->
receive
%% This will hang the gui until the sync is done. Not sure if
%% that's okay.
{server, {sync, Datum}} -> % Resync command from server.
gui_control(resync([Datum]));
{client, refresh} -> % Refresh request from display.
display:update(Data);
{server, Msg} ->
io:format("UI Rx: ~p~n", [Msg])
end,
gui_control(Data).
resync(Data) ->
receive
{server, {sync, Datum}} ->
resync([Datum|Data]);
{server, {done, Num}} ->
case length(Data) of
Num ->
Data;
_ ->
io:format("Got done before all the data were received.~n"),
send({sync})
end
after 5000 ->
io:format("Timed out waiting for data.~n"),
send({sync})
end.
它与this之后用gen_tcp和gen_server写的服务器进行通信。我的主要问题是我无法可靠地收到所有邮件。有时我会得到
(<0.2.0>) << {tcp,#Port<0.517>,
<<131,104,6,100,0,4,99,97,114,100,100,0,7,117,110,107,110,
111,119,110,100,0,7,117,110,107,110,111,119,110,106,106,
104,3,107,0,6,83,101,99,111,110,100,100,0,4,100,114,97,
119,97,2,131,104,6,100,0,4,99,97,114,100,100,0,7,117,110,
107,110,111,119,110,100,0,7,117,110,107,110,111,119,110,
106,106,104,3,107,0,6,83,101,99,111,110,100,100,0,4,100,
114,97,119,97,3,131,104,6,100,0,4,99,97,114,100,100,0,7,
117,110,107,110,111,119,110,100,0,7,117,110,107,110,111,
119,110,106,106,104,3,107,0,5,70,105,114,115,116,100,0,4,
100,114,97,119,97,0>>}
来自调试输出,但没有相应的Received TCP message on #Port<0.517>:...
消息。我也会看到这样的事情:
(<0.2.0>) << {io_reply,<0.24.0>,ok}
(<0.2.0>) << timeout
(<0.2.0>) << {io_reply,<0.24.0>,ok}
(<0.2.0>) << timeout
(<0.2.0>) << {io_reply,<0.24.0>,ok}
但net_client
的任何内容都没有收到。我已经通过wireshark观看了网络流量,并且我知道数据包正在到达他们应该去的地方并被ACK
编辑。我做错了什么?
编辑:我正在使用erl -smp enable -eval "client:start()."
调用此内容以防万一。
答案 0 :(得分:1)
我想基本的问题是'net_client'应该作为一个单独的过程产生..
在开始方法中,更改
register(client, self()),
net_client(Socket);
到
register(client, fun() -> net_client(Socket) end);
应该解决它..
答案 1 :(得分:1)
此外,我建议在跟踪时使用redbug(eper的一部分)https://github.com/massemanet/eper。它可以防止您在跟踪输出中淹没系统并提供简单的语法,例如:redbug:start(“mymod:foo - &gt; return”,[{msgs,10}])。跟踪对mymod:foo的所有调用以及这些调用返回的内容,但只给我10条跟踪消息。
答案 2 :(得分:1)
结果{packet, 0}
是我的问题。将其替换为{packet, 2}
,一切都很好。