本帖最后由 茶叶feng 于 2018-9-4 19:15 编辑  
 
shell脚本启动listen后accept总是报{error, closed}错误 
书上说,socket的生命周期和它的归属进程一样,也就是说归属进程死了,socket也就死了,之前没有对这句话理解好,当用shell脚本启动erlang虚拟机的时候,就出现了下面的问题 
以下是socket_example.erl部分的代码,用shell脚本直接执行erl -s socket_example -- start,但是执行gen_tcp:accept(LSocket)时候总是报{error, closed}错误 
- start() ->
 
 -     Args = [binary, {packet, 4}, {reuseaddr, false}, {active, true}],
 
 -     {ok, LSocket} = gen_tcp:listen(8088, Args),
 
 -     spawn(fun() -> wait_client(LSocket) end).
 
  
- wait_client(LSocket) ->
 
 -     case gen_tcp:accept(LSocket) of
 
 -         {ok, Socket} ->
 
 -             spawn(fun() -> wait_client(LSocket) end),
 
 -             loop(Socket);
 
 -         {error, Reason} ->
 
 -             io:format("error ~p~n", [Reason])
 
 -     end.
 
  复制代码 经过排查,原来是因为脚本执行完start/0函数时候,进程就结束了,socket的生存是跟归属进程一起的,所以,归属进程死了,socket也跟着死了,所以只要改变归属权就行了 
- start() ->
 
 -     Args = [binary, {packet, 4}, {reuseaddr, false}, {active, true}],
 
 -     {ok, LSocket} = gen_tcp:listen(8088, Args),
 
 -     Pid = spawn(fun() -> wait_client(LSocket) end),
 
 -     gen_tcp:controlling_process(LSocket, Pid).
 
  
- wait_client(LSocket) ->
 
 -     case gen_tcp:accept(LSocket) of
 
 -         {ok, Socket} ->
 
 -             Pid = spawn(fun() -> wait_client(LSocket) end),
 
 -             gen_tcp:controlling_process(LSocket, Pid),                
 
 -             loop(Socket);
 
 -         {error, Reason} ->
 
 -             io:format("error ~p~n", [Reason])
 
 -     end.
 
  复制代码 
 
 |