Решено: [Erlang] gen_tcp, {active,once}

Модератор: Модераторы разделов

Faurn
Сообщения: 12

Решено: [Erlang] gen_tcp, {active,once}

Сообщение Faurn »

Здравствуйте.

Изучаю вот Erlang. Появилась такая проблема:

1) Сделал примитивный tcp-сервер:

Код: Выделить всё

-module(tcp_server).
-compile(export_all).

main_server(Port) ->
    case gen_tcp:listen(Port,[list,{active,false}]) of
        {ok,Socket} ->
            tcp_server(Socket)
    end.

tcp_server(Socket) ->
    case gen_tcp:accept(Socket) of
        {ok,S} ->
            spawn(tcp_server,tcp_mess,[S]),
            tcp_server(Socket)
    end.

tcp_mess(S) ->
    inet:setopts(S,[{active,once}]),
    receive
        {tcp,S,Data} ->
            io:format("We get: [~w]~n",[Data]),
            tcp_mess(S);
        {tcp_closed,S} ->
            gen_tcp:close(S);
        {tcp_error,S,_} ->
            io:format("Error~n");
        _ ->
            io:format("Other~n"),
            tcp_mess(S)
    end.


2) Компилирую и запускаю:

Код: Выделить всё

c(tcp_server).
tcp_server:main_server(5678).


3) Делаю:

Код: Выделить всё

nmap localhost

Результат - сервер висит на 5678-ом порту

4) Пытаюсь подключиться:

telnet localhost 5678
opera - localhost:5678
самодельный простейший tcp-клиент на C

В каждом случае - "spawn(tcp_server,tcp_mess,[S])" выполняется и receive блокирует новый процесс навсегда. Т.е. даже "tcp_close" не приходит со временем

5) Переделываю программу на использование {active,false} и recv - все работает на "ура"

------------------------------------

Подскажите, пожалуйста, знающие люди - в чем моя ошибка?

ЗЫ:

Документацию на gen_tcp читал (первые версии сервера писаны по примеру оттуда - результат тот же), топик на dmitriid не помог
Спасибо сказали:
Faurn
Сообщения: 12

Re: Решено: [Erlang] gen_tcp, {active,once}

Сообщение Faurn »

Отвечу сам себе :rolleyes:

Ошибка исправлена путем замены:

Код: Выделить всё

spawn(tcp_server,tcp_mess,[S]),

на

Код: Выделить всё

tcp_mess(S),


Т.е. создание сокета (accept) и принятие сообщений из него должны находится в одном процессе. Получается, что сообщения отсылаются процессу, сделавшему accept, а не процессу, делающему setopts
Спасибо сказали: