帮助理解错误报告

时间:2011-08-14 03:17:42

标签: erlang

任何人都可以解释为什么我在运行时遇到以下错误:erl -noshell -s simple_server然后telnet 127.0.0.1 1084?代码本身低于错误消息。

  

=错误报告==== 2011年8月13日:: 23:12:05 ===过程中的错误< 0.30.0>   退出值:   {{badmatch,{错误,关闭}},[{simple_server,wait_accept,1}]}

  -module(simple_server).
  -compile(export_all).

  start() ->
      {ok, ListenSoc} = gen_tcp:listen(1084, [binary, {active, false}]),
      wait_accept(ListenSoc).

   wait_accept(ListenSoc) ->
      {ok, Socket} = gen_tcp:accept(ListenSoc),
      spawn(?MODULE, wait_accept, [ListenSoc]),
      send_resp(Socket).

  send_resp(Socket) ->
      gen_tcp:send(Socket, "Response from simple server...\n"),
      ok = gen_tcp:close(Socket).

2 个答案:

答案 0 :(得分:4)

这件事:

{{badmatch,{error,closed}},
 [{simple_server,wait_accept,1}]}

应该被理解为:“我们在simple_server:wait_accept / 1”,我们得到了一个badmatch错误(参见http://www.erlang.org/doc/reference_manual/errors.html#id81191)。这意味着我们的匹配表达式

{ok, Socket} = gen_tcp:accept(ListenSock),

返回{error, closed}(因为它是该函数中唯一的匹配表达式,它很简单)。为什么它返回对我来说有点模糊。最好的办法是调用start/0函数的进程已经终止,然后监听套接字因为终止而被关闭(这会自动发生)。请注意,erlang shell中的错误将重新启动它,因此关闭侦听套接字。

答案 1 :(得分:3)

创建套接字时,它会链接到当前进程,称为套接字控制进程。当控制进程终止时,所有链接的套接字都将被关闭。在您的情况下ListenSocsend_resp()结束时关闭(因此终止套接字的控制过程)并且新创建的进程中的gen_tcp:accept(ListenSoc)返回{error, closed}

最简单的解决方法是在wait_accept中添加对gen_tcp:contorolling_process/2的调用,如下所示:

...
Pid = spawn(?MODULE, wait_accept, [ListenSoc]),
ok = gen_tcp:controlling_process(ListenSoc, Pid),
...

但在实际项目中,最好循环监听套接字控制过程。您可以从Nicolas Buduroi回答中获得一个想法。