第一种是比较对的:
spawn出来的loop_socket进程仍然存在,你可以改以下代码:
loop_socket(Socket) ->
receive
{tcp,Socket, Binary} -> loop_socket(Socket);
{tcp_closed, Socket} -> exit;
{inet_async, _, _ , Reason} -> exit;
_Any -> exit;
end.
红的是我加的 只能 常正 才进入尾递归 出错或连接 断开就把进程结束
------------------
一平 广州红狼
地址:
广州天河软件园(高唐新建区)高普路广州电子商务产业园3楼C区
-------------------------------
号角吹响战斗序曲,要玩就玩《重装英雄》http://zzyx.3737.com/
------------------ 原始邮件 ------------------
发件人: "Yupei";
发送时间: 2012年5月15日(星期二) 下午4:27
收件人: "erlang-china";
主题: 由大意引发的Socket编程中的小错误
这邮件组好久没邮件了。发个今天排查的小错误凑个热闹。
原有一段代码是使用被动式消息接收(阻塞)方式,后来被改成 混合模式(半阻塞)。
结果莫名失效,排查代码,基本格式如下:
start() -> {ok, Listen} = gen_tcp:listen(8080,[{active,once}].
...........
loop_accept(Listen) ->
case gen_tcp:accept(Listen) of
{ok, Socket} ->
spawn(fun()->loop_socket(Socket) end),
loop_accept(Listen)
end.
loop_socket(Socket) ->
receive
{tcp,Socket, Binary} -> .....
{tcp_closed, Socket} -> ....
end.
代码本意是想接收到一个accept后,当前进程继续负责接收,用spawn出来的新进程来接手Socket请求,
现在情况是socket断开后,spawn出来的loop_socket进程仍然存在,
后将飘红处代码改为
spawn(fun()->loop_accept(Listen) end),
loop_socket(Socket)
便得以解决。即将当前进程处理socket请求,新开进程处理accept连接。
非阻塞的模式下,socket发来的消息是放到进程的msg-box里,新开进程receive是收不到数据的,大囧。