【问题标题】:Help Understanding Error Report帮助理解错误报告
【发布时间】:2011-10-26 15:41:09
【问题描述】:

谁能解释为什么我在运行时出现以下错误:erl -noshell -s simple_server 然后telnet 127.0.0.1 1084?代码本身位于错误消息下方。

=错误报告==== 2011 年 8 月 13 日::23:12:05 === 过程中出现错误 退出值: {{badmatch,{error,closed}},[{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).

【问题讨论】:

    标签: erlang


    【解决方案1】:

    这个东西:

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

    应该读作:“我们在 simple_server:wait_accept/1 中”并且我们收到了错误匹配错误(请参阅http://www.erlang.org/doc/reference_manual/errors.html#id81191)。这意味着我们的匹配表达式

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

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

    【讨论】:

      【解决方案2】:

      创建套接字时,它会链接到当前进程,即所谓的套接字控制进程。当控制进程终止时,所有链接的套接字都将关闭。在您的情况下,ListenSoc 在send_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 的答案中得到一个想法。

      【讨论】:

      • 真正正确的是,您应该在没有套接字的情况下生成进程,调用controlling_process/2,然后然后将套接字发送到进程一个消息。这是为了避免进程仍然能够从它还没有拥有的套接字中读取!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-16
      • 2023-03-21
      • 1970-01-01
      • 2017-04-07
      • 1970-01-01
      相关资源
      最近更新 更多