summaryrefslogtreecommitdiff
path: root/tcpserv.erl
diff options
context:
space:
mode:
Diffstat (limited to 'tcpserv.erl')
-rw-r--r--tcpserv.erl102
1 files changed, 102 insertions, 0 deletions
diff --git a/tcpserv.erl b/tcpserv.erl
new file mode 100644
index 0000000..91a25a6
--- /dev/null
+++ b/tcpserv.erl
@@ -0,0 +1,102 @@
+%%%-------------------------------------------------------------------
+%%% @author Joe Zhao
+%%% @copyright (C) 2014, <COMPANY>
+%%% @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, false}]).
+-define(DLYTIME,1000).
+%% API
+%%-export([]).
+
+lsockinit() -> ok.
+
+do_send(Sock,Pid,From) ->
+ receive
+ {From,exiting} -> ok;
+ {Pid,shutdown} ->
+ gen_tcp:close(Sock),
+ ok;
+ {_PPid,comm,Msg} ->
+ gen_tcp:send(Sock,Msg),
+ do_send(Sock,Pid,From)
+ end.
+
+do_recv(Sock,Pid,To,Cnt) ->
+ case gen_tcp:recv(Sock,0) of
+ {ok, B} ->
+ io:format("~p:\n ~p\n",[Cnt,B]),
+ manip_msg(Pid,To,B),
+ %% devicemon ! {self(),comm,Msg},
+ do_recv(Sock,Pid,To,Cnt+1);
+ {error, closed} ->
+ ok
+ end.
+
+%% Message manipulation & dispatch routine
+manip_msg(Pid,To,[0,0,Addr,MsgReq,MsgRes|Name]) ->
+ %% Operation command dispatch -> Complex(devicemon + Message handler)
+ cmdiface:reg_feedbackOps(Addr,Name,?DLYTIME,MsgReq,MsgRes,To);
+manip_msg(Pid,To,[0|Tail]) ->
+ %% Seperation from the next part
+ devicemon ! [0|Tail];
+manip_msg(Pid,To,[Addr,Cmd|Name]) when Addr<10 ->
+ %% Seperation from the next part
+ cmdiface:invoke_cmd(Addr,Name,[Cmd]);
+manip_msg(Pid,To,Msg) -> % This needs improvements
+ %% Fallback -> WTF
+ Pid ! {self(),comm,Msg}.
+
+createsock(Sock,Pid) ->
+ To=spawn(?MODULE,do_send,[Sock,Pid,self()]),
+ Pid ! {self(),create,To},
+ ok = do_recv(Sock,Pid,To,0),
+ To ! Pid ! {self(),exiting}.
+
+listenport(LSock,Pid) ->
+ {ok,Sock} = gen_tcp:accept(LSock),
+ spawn(?MODULE,createsock,[Sock,Pid]),
+ listenport(LSock,Pid).
+
+portlistener(Port,Pid) ->
+ {ok, LSock} = gen_tcp:listen(Port, [list, {packet, 1}, {active, false}]),
+ 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(). \ No newline at end of file