Erlang 问题gen_tcp:接受

Erlang 问题gen_tcp:接受,erlang,Erlang,我已经制作了一个tcp服务器,它会生成一个进程来监听传入的连接。以下是示例代码(从我的原始代码中删除了一些内容): 单元a: main([]) -> { ok, Pid } = b:start(), receive _ -> ok end. 模块b: -define(TCP_OPTIONS, [binary, { active, false}, { packet, 0 } , {reuseadd

我已经制作了一个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连接时,我都会在genu-tcp:accept上收到一个错误{error,closed}。这已经让我抓狂,想弄清楚到底发生了什么

谢谢,

您的“接受循环”实际上不是一个循环。。。这是人为的

您可能需要“do_accept_loop”和适当的“server_loop”来处理连接。看看

你想要的东西大致如下:

% 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.

@史酷特曼:我在回答中提供了一个链接。在
init
函数中,您调用
accept\u loop
,但您应该做的是调用一个为该连接生成服务器的函数。这就是为什么我提出了一些类似于
do\u accept
的建议。此外,您需要为生成的服务器提供适当的
循环
功能。您的
accept\u循环
根本没有循环。看看我提供的链接。哈哈,你比我快。看看你的例子,我把“spawn(server_listener,accept_loop,[LSocket])”(就在这里%do stuff之后)改为“accept_loop(LSocket)”,它成功了!因此,我认为spawn调用比我当前的进程退出慢,使我的accept套接字在新进程开始之前关闭。无论如何,谢谢!