%%%------------------------------------------------------------------- %%% @author Joe Zhao %%% @copyright (C) 2014, %%% @doc %%% TCP server for socket connections %%% One listenners of ports %%% Spawns one receiver and one sender for different socket. %%% @end %%% Created : 27. 四月 2014 20:52 %%%------------------------------------------------------------------- -module(tcpserv). -author("Joe Zhao"). -compile([debug_info,export_all]). -define(TCP_OPTIONS,[list, {packet, 1}, {active, true}]). -define(DLYTIME,1000). %% API %%-export([]). lsockinit() -> ok. do_loop(Sock,Pid,N) -> receive {tcp,Sock,Data} -> io:format("~p:\n ~p\n",[N,Data]), manip_msg(Pid,Data), do_loop(Sock,Pid,N+1); {tcp_closed,Sock} -> ok; {Pid,shutdown} -> gen_tcp:close(Sock); {_PPid,comm,Msg} -> gen_tcp:send(Sock,Msg), do_loop(Sock,Pid,N) end. %% Message manipulation & dispatch routine manip_msg(_Pid,[0,0,Addr,MsgReq,MsgRes|Name]) -> %% Operation command dispatch -> Complex(devicemon + Message handler) cmdiface:reg_feedbackOps(Addr,Name,?DLYTIME,[MsgReq],[MsgRes],self()); manip_msg(_Pid,[0|Tail]) -> %% Seperation from the next part devicemon ! {self(),comm,[0|Tail]}; manip_msg(_Pid,[Addr,Cmd|Name]) when Addr<10 -> %% Seperation from the next part cmdiface:invoke_cmd(Addr,Name,[Cmd]); manip_msg(Pid,Msg) -> % This needs improvements %% Fallback -> WTF Pid ! {self(),comm,Msg}. createsock(Sock,Pid) -> Pid ! {self(),create,self()}, ok = do_loop(Sock,Pid,0), Pid ! {self(),exiting}. listenport(LSock,Pid) -> {ok,Sock} = gen_tcp:accept(LSock), gen_tcp:controlling_process(Sock,spawn(?MODULE,createsock,[Sock,Pid])), listenport(LSock,Pid). portlistener(Port,Pid) -> {ok, LSock} = gen_tcp:listen(Port, ?TCP_OPTIONS), listenport(LSock,Pid). monloop(Procs) -> receive {_Pid,shutdown} -> [ To ! shutdown || {_From,To} <- orddict:to_list(Procs) ]; {Pid,create,To} -> monloop(orddict:store(Pid,To,Procs)); {Pid,exiting} -> monloop(orddict:erase(Pid,Procs)); {_Pid,comm,Msg} -> [ To ! {self(),comm,Msg} || {_From,To} <- orddict:to_list(Procs) ], monloop(Procs) end. tcpmon(Port) -> Lis=spawn(?MODULE,portlistener,[Port,self()]), register(?MODULE,self()), monloop(orddict:new()), exit(Lis,shutdown). start(Port) -> spawn(?MODULE,tcpmon,[Port]). trap() -> trap(). test() -> start(5575), trap().