gpt4 book ai didi

erlang - gen_tcp smushed 消息

转载 作者:行者123 更新时间:2023-12-04 18:15:39 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Erlang server, Java client - TCP messages get split?

(3 个回答)


7年前关闭。




我正在使用 this 中的 socket_server客户端和服务器的教程和以下代码:

服务器:

-module(echo_server).
-export([start/0, loop/1]).

% echo_server specific code
start() ->
spawn(socket_server, start, [?MODULE, 7000, {?MODULE, loop}]).

loop(Socket) ->
case gen_tcp:recv(Socket, 0) of
{ok, Message} ->
Msg = binary_to_term(Message),
case Msg of
start ->
io:format("Got start message on socket ~p.~n", [Socket]),
send_count(Socket, 10),
gen_tcp:close(Socket);
Other ->
io:format("Got message on socket ~p: ~p~n",
[Socket, Other])
end;
{error, closed} ->
io:format("Got closed message on socket ~p.~n", [Socket]),
ok;
Error ->
io:format("Got bad message: ~p on socket ~p.~n", [Error, Socket])
end.

send_count(_Socket, 0) ->
ok;
send_count(Socket, Num) ->
io:format("Sending ~p to ~p.~n", [Num, Socket]),
gen_tcp:send(Socket, term_to_binary(Num)),
send_count(Socket, Num - 1).

客户:
-module(echo_client).
-export([start/0, do_stuff/0]).


send(Socket, Msg) ->
gen_tcp:send(Socket, term_to_binary(Msg)).

start() ->
dbg:tracer(),
Pid = spawn(?MODULE, do_stuff, []),
dbg:p(Pid, r).

do_stuff() ->
case gen_tcp:connect("localhost", 7000, [binary, {packet, 0}]) of
{ok, Socket} ->
send(Socket, start),
rx_loop(Socket);
Error ->
io:format("Error connecting to server: ~p~n", [Error])
end.

rx_loop(Socket) ->
receive
{tcp, Socket, Message} ->
Msg = binary_to_term(Message),
io:format("Received message: ~p~n", [Msg]),
rx_loop(Socket)
after 5000 ->
finish_loop(Socket)
end.

finish_loop(Socket) ->
receive
{tcp, Socket, Message} ->
Msg = binary_to_term(Message),
io:format("Received message: ~p~n", [Msg]),
rx_loop(Socket);
{tcp_closed, Socket} ->
io:format("Server terminated connection.~n"),
exit(normal);
Error ->
io:format("Received bad message: ~p~n", [Error]),
rx_loop(Socket)
end.

我正在调用 echo_server:start()echo_client:start()从同一系统上的不同外壳,按顺序。这是我看到的:

服务器似乎工作得很好。
1>echo_server:start().
<0.39.0>
Got start message on socket #Port<0.2041>.
Sending 10 to #Port<0.2041>.
Sending 9 to #Port<0.2041>.
Sending 8 to #Port<0.2041>.
Sending 7 to #Port<0.2041>.
Sending 6 to #Port<0.2041>.
Sending 5 to #Port<0.2041>.
Sending 4 to #Port<0.2041>.
Sending 3 to #Port<0.2041>.
Sending 2 to #Port<0.2041>.
Sending 1 to #Port<0.2041>.

客户端并没有完全正确地获取所有消息:
2> echo_client:start().
{ok,[{matched,nonode@nohost,1}]}
3> (<0.41.0>) << {code_server,{module,gen_tcp}}
(<0.41.0>) << {code_server,{module,inet_tcp}}
(<0.41.0>) << {#Ref<0.0.0.74>,{ok,<0.43.0>}}
(<0.41.0>) << {#Ref<0.0.0.76>,
{ok,<<4,0,0,0,2,127,0,0,1,127,0,0,1,0,0,0,3,108,111,99,97,108,
104,111,115,116,0,105,112,54,45,108,111,99,97,108,104,
111,115,116,0,105,112,54,45,108,111,111,112,98,97,99,
107,0>>}}
(<0.41.0>) << {inet_async,#Port<0.2058>,0,ok}
(<0.41.0>) << {inet_reply,#Port<0.2058>,ok}
Received message: 10
3> (<0.41.0>) << {tcp,#Port<0.2058>,<<131,97,10>>}
Received message: 9
3> (<0.41.0>) << {io_reply,<0.25.0>,ok}
(<0.41.0>) << timeout
(<0.41.0>) << {tcp,#Port<0.2058>,<<131,97,9>>}
(<0.41.0>) << {io_reply,<0.25.0>,ok}
Received message: 8
Received message: 5
Received message: 4
Received message: 3
Received message: 2
Received message: 1
3> (<0.41.0>) << timeout
(<0.41.0>) << {tcp,#Port<0.2058>,<<131,97,8,131,97,7,131,97,6>>} %% <---This guy here
(<0.41.0>) << {io_reply,<0.25.0>,ok}
(<0.41.0>) << {tcp,#Port<0.2058>,<<131,97,5>>}
(<0.41.0>) << timeout
(<0.41.0>) << {io_reply,<0.25.0>,ok}
(<0.41.0>) << timeout
(<0.41.0>) << {tcp,#Port<0.2058>,<<131,97,4>>}
(<0.41.0>) << {io_reply,<0.25.0>,ok}
(<0.41.0>) << timeout
(<0.41.0>) << {tcp,#Port<0.2058>,<<131,97,3>>}
(<0.41.0>) << {io_reply,<0.25.0>,ok}
(<0.41.0>) << timeout
(<0.41.0>) << {tcp,#Port<0.2058>,<<131,97,2>>}
(<0.41.0>) << {io_reply,<0.25.0>,ok}
(<0.41.0>) << timeout
(<0.41.0>) << {tcp,#Port<0.2058>,<<131,97,1>>}
(<0.41.0>) << {io_reply,<0.25.0>,ok}
(<0.41.0>) << {tcp_closed,#Port<0.2058>}
(<0.41.0>) << timeout
Server terminated connection.
3> (<0.41.0>) << timeout
(<0.41.0>) << {io_reply,<0.25.0>,ok}
(<0.41.0>) << timeout

如果我查看 lo 上的网络流量,我看到每个倒计时的数字都非常干净的 PSH/ACK 对。我在上面指出的行显示了两个数据包出现在一条消息中:7 和 6。它们作为两个单独的 TCP 数据包通过网络传入。任何人都知道为什么他们会被混在一起或如何解开他们?

最佳答案

为什么它们在接收端被“弄脏”:因为 TCP 是一种流协议(protocol),
并且发送/接收调用不需要与
网络数据包(即使它们通过网络以这种方式到达)。

如何“取消”它们:更改您的 TCP 协议(protocol)以包含消息分隔符,
因此您可以从流中提取消息,而无需知道数据包的位置
边界是;或使用 UDP 而不是 TCP。

关于erlang - gen_tcp smushed 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4209261/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com