Сделал небольшой тестовый пример:
-module(t).
-export([
s/0,
s/1,
t/1
]).
-define(SPORT, 54321).
s() ->
case gen_tcp:listen(?SPORT, [binary]) of
{ok, LS} ->
s(LS);
Err ->
io:format(\"Server listen error: ~p~n\", [Err])
end.
s(LSock) ->
case gen_tcp:accept(LSock) of
{ok, Sock} ->
io:format(\"Accept connection: ~p~n\", [Sock]),
spawn(?MODULE, s, [LSock]),
sl(Sock);
Err ->
io:format(\"Server accept error: ~p~n\", [Err])
end.
sl(Sock) ->
receive
{tcp, Sock, Data} ->
Disp = binary_to_term(Data),
io:format(\"Receive data: ~p~n\", [Disp]),
sl(Sock);
All ->
io:format(\"Catch undef data on server: ~p~n\", [All]),
sl(Sock)
after 10000 ->
Ret = gen_tcp:close(Sock),
io:format(\"Connection ~p close.... ~p~n\", [Sock, Ret])
end.
t(N) ->
case gen_tcp:connect(\"localhost\", ?SPORT, [binary]) of
{ok, Sock} ->
msg(Sock, N);
Err ->
io:format(\"Client connect error: ~p~n\", [Err])
end.
msg(_, 0) ->
io:format(\"All test done~n\");
msg(S, N) ->
gen_tcp:send(S, term_to_binary(\"caramba\")),
gen_tcp:send(S, term_to_binary(N)),
io:format(\"Message ~p send~n\", [N]),
NN = N - 1,
msg(S, NN).
Тут s() запускеает сервак который слушает порт, устанавливает соединение и просто распечатывает принимаемые сообщения. t(N) это тестовый клиент - соединяется с серваком и отправляет ему N * 2 пакетов: в первом строка "caramba", а во втором номер сообщения. Проблемма в том что код не работает.
Запускаю в 2-х окнах на локальной машине.
Клиент:
Erlang (BEAM) emulator version 5.5.5 [async-threads:0] Eshell V5.5.5 (abort with ^G) 1> t:t(10). Message 10 send Message 9 send Message 8 send Message 7 send Message 6 send Message 5 send Message 4 send Message 3 send Message 2 send Message 1 send All test done ok 2>
Сервер:
Erlang (BEAM) emulator version 5.5.5 [async-threads:0] Eshell V5.5.5 (abort with ^G) 1> t:s(). Accept connection: #Port<0.98> Receive data: \"caramba\" Receive data: \"caramba\" Receive data: \"caramba\" Receive data: \"caramba\" Receive data: \"caramba\" Receive data: \"caramba\" Receive data: \"caramba\" Receive data: 2 Receive data: \"caramba\" Connection #Port<0.98> close.... ok ok 2>
Как видно сервер не принимает часть пакетов. Всего один раз он смог принять номер сообщения и только 8 раз из 10 успел принять строку. Хотя TCP гарантирует что пакеты придут в правильном порядке. Когда ставлю задержку между отправкой пакетов на клиенте - сервер начинает их правильно принимать. Что это? Баг в библиотеке gen_tcp или я что-то не так делаю? Можен настроить надо ещё что?
