任何人都可以解释为什么我在运行时遇到以下错误: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).
答案 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)
创建套接字时,它会链接到当前进程,称为套接字控制进程。当控制进程终止时,所有链接的套接字都将被关闭。在您的情况下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
回答中获得一个想法。