问题gen_tcp:接受

时间:2009-11-30 18:32:57

标签: erlang

我已经创建了一个tcp服务器,它会生成一个监听传入连接的进程。以下是示例代码(从原始代码中删除了一些内容):

模块a:

main([]) ->
    { ok, Pid } = b:start(),
    receive
            _ ->
                    ok
    end.

模块b:

-define(TCP_OPTIONS, [binary, { active, false}, { packet, 0 } , {reuseaddr, true}]).

...

start_link(Port) ->
    Pid = spawn_link(server_listener, init, [ Port ]),
    { ok , self() }.

init(Port, Processor) ->
    case gen_tcp:listen(Port, ?TCP_OPTIONS) of
     { ok , LSocket } ->
           accept_loop(LSocket);
     { error, Reason } ->
        { stop, Reason }
     end.

accept_loop( LSocket) ->
  ?LOG("Current socket acceptor PID [~w]~n", [self()]),
  case gen_tcp:accept(LSocket) of
      { ok, Socket } ->   
      %do stuff here
         spawn(server_listener , accept_loop, [ LSocket ]);
      { error, Reason }  ->
         ?LOG("Error accepting socket! [ ~s ]~n", [ Reason ])   
  end.

问题是:每次尝试从此端口上的telnet连接时,我在gen_tcp:accept上收到错误{error,closed}。这已经让我疯狂地试图找出正在发生的事情。

谢谢,

1 个答案:

答案 0 :(得分:2)

你的“接受循环”实际上不是一个循环......它是人为的。

您可能需要“do_accept_loop”和正确的“server_loop”来处理连接。请查看 this

你想要的东西是:

% Call echo:listen(Port) to start the service.
listen(Port) ->
    {ok, LSocket} = gen_tcp:listen(Port, ?TCP_OPTIONS),
    accept(LSocket).

% Wait for incoming connections and spawn the echo loop when we get one.
accept(LSocket) ->
    {ok, Socket} = gen_tcp:accept(LSocket),
    spawn(fun() -> loop(Socket) end),
    accept(LSocket).

% Echo back whatever data we receive on Socket.
loop(Socket) ->
    case gen_tcp:recv(Socket, 0) of
        {ok, Data} ->
            gen_tcp:send(Socket, Data),
            loop(Socket);
        {error, closed} ->
            ok
    end.