Erlang по-русски. Форум » Erlang

Рейтинг топика

Всего проглосовало:
Ваша оценка:

Проблемма с gen_tcp

(4 posts)

  1. Сделал небольшой тестовый пример:

    -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 или я что-то не так делаю? Можен настроить надо ещё что?

    Отправлено 12 мес. назад #
  2. В опциях сокета стоит только binary.

    Отправлено 12 мес. назад #
  3. Прошу прощения за долгое молчание

    В общем, ответ здесь: http://rsdn.ru/forum/message/2699995.1.aspx и более простой вариант здесь: http://rsdn.ru/forum/message/2700003.1.aspx

    Отправлено 11 мес. назад #
  4. Работает! Спасибо!

    Отправлено 11 мес. назад #

RSS экспорт этой темы

Отправить сообщение

Вы должны войти в систему, чтобы оставлять сообщения.