`

[练习]erlang编程练习3:echo程序实现

 
阅读更多

这段程序一些地方参考:

写道
http://www.erlang.org/upload/klacke_examples/chargen.erl

依旧是erlang官网的一个example

 

自己独立写的时候 做了一个同步的版本 接下去改成异步

改成异步的时候没有把gen_tcp:listener那段独立到循环的进程中去

调用函数那段就运行完了(那么tcp的端口就相当于直接关闭了)

苦恼不已 后来按照以上程序在一些地方改了改 加上了 关闭 的操作

通过进程链接来关闭已经在服务的进程(就是一层的监督结构)

 

这边记点笔记,说说一些API调用之类的

 

代码如下:

 

-module(server).
-export([start/0,start/1,loop_accept/2,listener/1]).
-define(DEAFULT_PORT,1236).

start() ->
 start(?DEAFULT_PORT).

start(Port) ->
  spawn_link(?MODULE,listener,[Port]).

listener(Port) ->
 case gen_tcp:listen(Port,[{active,false}]) of
   {ok,LSocket}-> process_flag(trap_exit,true),
                  spawn_link(?MODULE,loop_accept,[LSocket,self()]),
                  loop(LSocket);   
         Other -> Other 
  end.

loop(LSocket) ->
  receive
    continue ->
      	spawn_link(?MODULE,loop_accept,[LSocket,self()]),
		loop(LSocket);
    {stop,Reason} ->
	    exit(Reason);
    stop ->
	    exit(shutdown);
	Other ->
	    io:format("link process exit:~p~n",[Other]),
		loop(LSocket)
  end.
    
loop_accept(Ls,Pid) -> 
  io:format("accept now~n"),
     case gen_tcp:accept(Ls) of
       {error, Reason} -> Pid ! {stop,Reason};
	   {ok,Socket} -> Pid ! continue,worker(Socket) end.

	   
worker(Socket) ->
    %%io:format("work now~n"),
	case gen_tcp:recv(Socket, 0) of
	   {ok, Packet} ->
	     gen_tcp:send(Socket,Packet),worker(Socket);
	   {error, Reason} ->
	     %%io:format("Socket ~w closed [~w]~w",[Socket,self(),Reason]),
		 exit(Reason)
    end.
		 

 

代码的基本流程很简单:

  1. server:start/0/1启动应用
  2. 产生并连接进程sub(监督者进程 同时用来监视进行echo的进程的情况)
  3. sub用来启动监听的进程acc(该进程一启动就会监听 有连接进来给work处理)
  4. sub接受到退出信息(stop)后就退出并发送shutdown信息 其他的acc进程也跟着退出

 

代码说明:

listen时使用了active,false的参数 说明所有进来的信息要通过gen_tcp:recv/2才能获取到(而 active,true或者 active,once则会直接把信息传送给进程 区别是后者只传送一次(所以在接受时要通过inet:setopts/2不断重置为{active,once})

此外设置成 active,false 接受的消息要么是{ok,内容} 要么是{error,Reason}

而其他两种收到的形式是  {tcp,S,Data} {tcp_closed,S}(那个S就是通信用的Socket) 

 

附带一张 链接时退出信号传播时的对应表现:

捕获状态              退出信号(原因)            动作  
       true                     kill                      消亡,向链接的进程广播退出信号(killed)
       true                     X                        将{'EXIT', Pid, X} 加入到邮箱
       false                    normal               不做任何事
       false                    kill                       消亡,向链接的进程广播退出信号(killed)
       false                    X                         消亡,向链接的进程广播退出信号X
该表来源:http://www.cnblogs.com/fangjie008/archive/2012/08/28/2660361.html
捕获指的是process_flag(trap_exit,true).
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics