设为首页收藏本站

Erlang中文论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 24780|回复: 0
打印 上一主题 下一主题

对socket执行gen_tcp:accept/1返回{error, closed}

[复制链接]
跳转到指定楼层
楼主
发表于 2018-9-4 19:13:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 茶叶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}错误
  1. start() ->
  2.     Args = [binary, {packet, 4}, {reuseaddr, false}, {active, true}],
  3.     {ok, LSocket} = gen_tcp:listen(8088, Args),
  4.     spawn(fun() -> wait_client(LSocket) end).

  5. wait_client(LSocket) ->
  6.     case gen_tcp:accept(LSocket) of
  7.         {ok, Socket} ->
  8.             spawn(fun() -> wait_client(LSocket) end),
  9.             loop(Socket);
  10.         {error, Reason} ->
  11.             io:format("error ~p~n", [Reason])
  12.     end.
复制代码
经过排查,原来是因为脚本执行完start/0函数时候,进程就结束了,socket的生存是跟归属进程一起的,所以,归属进程死了,socket也跟着死了,所以只要改变归属权就行了
  1. start() ->
  2.     Args = [binary, {packet, 4}, {reuseaddr, false}, {active, true}],
  3.     {ok, LSocket} = gen_tcp:listen(8088, Args),
  4.     Pid = spawn(fun() -> wait_client(LSocket) end),
  5.     gen_tcp:controlling_process(LSocket, Pid).

  6. wait_client(LSocket) ->
  7.     case gen_tcp:accept(LSocket) of
  8.         {ok, Socket} ->
  9.             Pid = spawn(fun() -> wait_client(LSocket) end),
  10.             gen_tcp:controlling_process(LSocket, Pid),               
  11.             loop(Socket);
  12.         {error, Reason} ->
  13.             io:format("error ~p~n", [Reason])
  14.     end.
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|Erldoc.com  

GMT+8, 2024-11-21 17:44 , Processed in 0.336842 second(s), 10 queries , File On.

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表