1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
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().
|