aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/kernel/test/Makefile1
-rw-r--r--lib/kernel/test/socket_client.erl252
-rw-r--r--lib/kernel/test/socket_lib.erl129
-rw-r--r--lib/kernel/test/socket_server.erl237
4 files changed, 462 insertions, 157 deletions
diff --git a/lib/kernel/test/Makefile b/lib/kernel/test/Makefile
index 07e7922d3d..051fac25af 100644
--- a/lib/kernel/test/Makefile
+++ b/lib/kernel/test/Makefile
@@ -25,6 +25,7 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk
# ----------------------------------------------------
SOCKET_MODULES = \
+ socket_lib \
socket_server \
socket_client
diff --git a/lib/kernel/test/socket_client.erl b/lib/kernel/test/socket_client.erl
index a284777046..0b570e1f71 100644
--- a/lib/kernel/test/socket_client.erl
+++ b/lib/kernel/test/socket_client.erl
@@ -1,17 +1,34 @@
-%%%-------------------------------------------------------------------
-%%% @author Micael Karlberg <[email protected]>
-%%% @copyright (C) 2018, Micael Karlberg
-%%% @doc
-%%%
-%%% @end
-%%% Created : 27 Jun 2018 by Micael Karlberg <[email protected]>
-%%%-------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2018-2018. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
-module(socket_client).
--export([start/1]).
+-export([
+ start/1,
+ start_tcp/1, start_tcp/2,
+ start_udp/1, start_udp/2
+ ]).
+
+-define(LIB, socket_lib).
--define(REQ, 0).
--define(REP, 1).
+-record(client, {socket, type, dest, msg_id = 1}).
start(Port) ->
start_tcp(Port).
@@ -19,22 +36,77 @@ start(Port) ->
start_tcp(Port) ->
start(inet, stream, tcp, Port).
+start_tcp(Addr, Port) when (size(Addr) =:= 4) ->
+ start(inet, stream, tcp, Addr, Port);
+start_tcp(Addr, Port) when (size(Addr) =:= 8) ->
+ start(inet6, stream, tcp, Addr, Port).
+
+
+start_udp(Port) ->
+ start(inet, dgram, udp, Port).
+
+start_udp(Addr, Port) when (size(Addr) =:= 4) ->
+ start(inet, dgram, udp, Addr, Port);
+start_udp(Addr, Port) when (size(Addr) =:= 8) ->
+ start(inet6, dgram, udp, Addr, Port).
+
+
start(Domain, Type, Proto, Port) ->
+ start(Domain, Type, Proto, which_addr(Domain), Port).
+
+start(Domain, Type, Proto, Addr, Port) ->
+ put(sname, "starter"),
+ SA = #{family => Domain,
+ addr => Addr,
+ port => Port},
+ do_start(Domain, Type, Proto, SA).
+
+do_start(Domain, stream = Type, Proto, SA) ->
try do_init(Domain, Type, Proto) of
Sock ->
- connect(Sock, Domain, Port),
+ connect(Sock, SA),
+ i("connected: "
+ "~n From: ~p"
+ "~n To: ~p",
+ [
+ case socket:sockname(Sock) of
+ {ok, Name} -> Name;
+ {error, _} = NE -> NE
+ end,
+ case socket:peername(Sock) of
+ {ok, Name} -> Name;
+ {error, _} = PE -> PE
+ end
+ ]),
%% Give the server some time...
- p("wait some", []),
- %% sleep(5000),
+ i("wait some", []),
+ ?LIB:sleep(5000),
%% ok = socket:close(Sock),
- send_loop(Sock)
+ send_loop(#client{socket = Sock,
+ type = Type})
+ catch
+ throw:E ->
+ e("Failed initiate: "
+ "~n Error: ~p", [E])
+ end;
+do_start(Domain, dgram = Type, Proto, SA) ->
+ try do_init(Domain, Type, Proto) of
+ Sock ->
+ %% Give the server some time...
+ i("wait some", []),
+ ?LIB:sleep(5000),
+ %% ok = socket:close(Sock),
+ send_loop(#client{socket = Sock,
+ type = Type,
+ dest = SA})
catch
throw:E ->
e("Failed initiate: "
"~n Error: ~p", [E])
end.
-do_init(Domain, Type, Proto) ->
+
+do_init(Domain, stream = Type, Proto) ->
i("try (socket) open"),
Sock = case socket:open(Domain, Type, Proto) of
{ok, S} ->
@@ -48,8 +120,23 @@ do_init(Domain, Type, Proto) ->
Sock;
{error, BReason} ->
throw({bind, BReason})
+ end;
+do_init(Domain, dgram = Type, Proto) ->
+ i("try (socket) open"),
+ Sock = case socket:open(Domain, Type, Proto) of
+ {ok, S} ->
+ S;
+ {error, OReason} ->
+ throw({open, OReason})
+ end,
+ case socket:bind(Sock, any) of
+ {ok, _} ->
+ Sock;
+ {error, BReason} ->
+ throw({bind, BReason})
end.
+
which_addr(Domain) ->
Iflist = case inet:getifaddrs() of
{ok, IFL} ->
@@ -60,16 +147,11 @@ which_addr(Domain) ->
which_addr(Domain, Iflist).
-connect(Sock, Domain, Port) ->
- Addr = which_addr(Domain),
- SA = #{family => Domain,
- addr => Addr,
- port => Port},
+connect(Sock, SA) ->
i("try (socket) connect to:"
"~n ~p", [SA]),
case socket:connect(Sock, SA) of
ok ->
- i("connected"),
ok;
{error, Reason} ->
e("connect failure: "
@@ -78,22 +160,23 @@ connect(Sock, Domain, Port) ->
end.
-send_loop(Sock) ->
- send_loop(Sock, 1).
-
-send_loop(Sock, N) when (N =< 10) ->
+send_loop(#client{msg_id = N} = C) when (N =< 10) ->
i("try send request ~w", [N]),
- Req = enc_req_msg(N, "hejsan"),
- case socket:send(Sock, Req) of
+ Req = ?LIB:enc_req_msg(N, "hejsan"),
+ case send(C, Req) of
ok ->
i("request ~w sent - now try read answer", [N]),
- case socket:recv(Sock, 0) of
- {ok, Msg} ->
- i("received ~w bytes of data", [size(Msg)]),
- case dec_msg(Msg) of
+ case recv(C) of
+ {ok, {Source, Msg}} ->
+ i("received ~w bytes of data~s",
+ [size(Msg), case Source of
+ undefined -> "";
+ _ -> ?LIB:f(" from:~n ~p", [Source])
+ end]),
+ case ?LIB:dec_msg(Msg) of
{reply, N, Reply} ->
i("received reply ~w: ~p", [N, Reply]),
- send_loop(Sock, N+1)
+ send_loop(C#client{msg_id = N+1})
end;
{error, RReason} ->
e("Failed recv response for request ~w: "
@@ -105,7 +188,7 @@ send_loop(Sock, N) when (N =< 10) ->
"~n ~p", [SReason]),
exit({failed_send, SReason})
end;
-send_loop(Sock, _N) ->
+send_loop(#client{socket = Sock}) ->
i("we are done - close the socket when: "
"~n ~p", [socket:info()]),
ok = socket:close(Sock),
@@ -113,6 +196,25 @@ send_loop(Sock, _N) ->
"~n ~p", [socket:info()]).
+send(#client{socket = Sock, type = stream}, Msg) ->
+ socket:send(Sock, Msg);
+send(#client{socket = Sock, type = dgram, dest = Dest}, Msg) ->
+ %% i("try send to: "
+ %% "~n ~p", [Dest]),
+ %% ok = socket:setopt(Sock, otp, debug, true),
+ socket:sendto(Sock, Msg, Dest).
+
+recv(#client{socket = Sock, type = stream}) ->
+ case socket:recv(Sock) of
+ {ok, Msg} ->
+ {ok, {undefined, Msg}};
+ {error, _} = ERROR ->
+ ERROR
+ end;
+recv(#client{socket = Sock, type = dgram}) ->
+ socket:recvfrom(Sock).
+
+
which_addr(_Domain, []) ->
throw(no_address);
which_addr(Domain, [{Name, IFO}|_IFL]) when (Name =/= "lo") ->
@@ -130,68 +232,66 @@ which_addr2(Domain, [_|IFO]) ->
%% ---
-enc_req_msg(N, Data) ->
- enc_msg(?REQ, N, Data).
+%% enc_req_msg(N, Data) ->
+%% enc_msg(?REQ, N, Data).
-enc_rep_msg(N, Data) ->
- enc_msg(?REP, N, Data).
+%% enc_rep_msg(N, Data) ->
+%% enc_msg(?REP, N, Data).
-enc_msg(Type, N, Data) when is_list(Data) ->
- enc_msg(Type, N, list_to_binary(Data));
-enc_msg(Type, N, Data)
- when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) ->
- <<Type:32/integer, N:32/integer, Data/binary>>.
+%% enc_msg(Type, N, Data) when is_list(Data) ->
+%% enc_msg(Type, N, list_to_binary(Data));
+%% enc_msg(Type, N, Data)
+%% when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) ->
+%% <<Type:32/integer, N:32/integer, Data/binary>>.
-dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) ->
- {request, N, Data};
-dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) ->
- {reply, N, Data}.
+%% dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) ->
+%% {request, N, Data};
+%% dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) ->
+%% {reply, N, Data}.
%% ---
-sleep(T) ->
- receive after T -> ok end.
+%% sleep(T) ->
+%% receive after T -> ok end.
%% ---
-formated_timestamp() ->
- format_timestamp(os:timestamp()).
+%% formated_timestamp() ->
+%% format_timestamp(os:timestamp()).
-format_timestamp(Now) ->
- N2T = fun(N) -> calendar:now_to_local_time(N) end,
- format_timestamp(Now, N2T, true).
+%% format_timestamp(Now) ->
+%% N2T = fun(N) -> calendar:now_to_local_time(N) end,
+%% format_timestamp(Now, N2T, true).
-format_timestamp({_N1, _N2, N3} = N, N2T, true) ->
- FormatExtra = ".~.2.0w",
- ArgsExtra = [N3 div 10000],
- format_timestamp(N, N2T, FormatExtra, ArgsExtra);
-format_timestamp({_N1, _N2, _N3} = N, N2T, false) ->
- FormatExtra = "",
- ArgsExtra = [],
- format_timestamp(N, N2T, FormatExtra, ArgsExtra).
+%% format_timestamp({_N1, _N2, N3} = N, N2T, true) ->
+%% FormatExtra = ".~.2.0w",
+%% ArgsExtra = [N3 div 10000],
+%% format_timestamp(N, N2T, FormatExtra, ArgsExtra);
+%% format_timestamp({_N1, _N2, _N3} = N, N2T, false) ->
+%% FormatExtra = "",
+%% ArgsExtra = [],
+%% format_timestamp(N, N2T, FormatExtra, ArgsExtra).
-format_timestamp(N, N2T, FormatExtra, ArgsExtra) ->
- {Date, Time} = N2T(N),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra,
- [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra),
- lists:flatten(FormatDate).
+%% format_timestamp(N, N2T, FormatExtra, ArgsExtra) ->
+%% {Date, Time} = N2T(N),
+%% {YYYY,MM,DD} = Date,
+%% {Hour,Min,Sec} = Time,
+%% FormatDate =
+%% io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra,
+%% [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra),
+%% lists:flatten(FormatDate).
%% ---
e(F, A) ->
- p("<ERROR> " ++ F, A).
+ ?LIB:e(F, A).
i(F) ->
- i(F, []).
+ ?LIB:i(F).
+
i(F, A) ->
- p("*** " ++ F, A).
-
-p(F, A) ->
- io:format("[client,~p][~s] " ++ F ++ "~n", [self(),formated_timestamp()|A]).
+ ?LIB:i(F, A).
diff --git a/lib/kernel/test/socket_lib.erl b/lib/kernel/test/socket_lib.erl
new file mode 100644
index 0000000000..0eed81d61a
--- /dev/null
+++ b/lib/kernel/test/socket_lib.erl
@@ -0,0 +1,129 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2018-2018. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(socket_lib).
+
+-export([
+ sleep/1,
+ enc_req_msg/2, enc_rep_msg/2,
+ enc_msg/3, dec_msg/1,
+ request/3, reply/4,
+ f/2,
+ i/1, i/2,
+ e/2
+ ]).
+
+
+-define(REQ, 0).
+-define(REP, 1).
+
+
+%% ---
+
+sleep(T) ->
+ receive after T -> ok end.
+
+
+%% ---
+
+enc_req_msg(N, Data) ->
+ enc_msg(?REQ, N, Data).
+
+enc_rep_msg(N, Data) ->
+ enc_msg(?REP, N, Data).
+
+enc_msg(Type, N, Data) when is_list(Data) ->
+ enc_msg(Type, N, list_to_binary(Data));
+enc_msg(Type, N, Data)
+ when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) ->
+ <<Type:32/integer, N:32/integer, Data/binary>>.
+
+dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) ->
+ {request, N, Data};
+dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) ->
+ {reply, N, Data}.
+
+
+%% ---
+
+request(Tag, Pid, Request) ->
+ Ref = make_ref(),
+ Pid ! {Tag, self(), Ref, Request},
+ receive
+ {Tag, Pid, Ref, Reply} ->
+ Reply
+ end.
+
+reply(Tag, Pid, Ref, Reply) ->
+ Pid ! {Tag, self(), Ref, Reply}.
+
+
+%% ---
+
+f(F, A) ->
+ lists:flatten(io_lib:format(F, A)).
+
+
+%% ---
+
+e(F, A) ->
+ p("<ERROR> " ++ F, A).
+
+i(F) ->
+ i(F, []).
+i(F, A) ->
+ p("*** " ++ F, A).
+
+p(F, A) ->
+ p(get(sname), F, A).
+
+p(SName, F, A) ->
+ io:format("[~s,~p][~s] " ++ F ++ "~n",
+ [SName,self(),formated_timestamp()|A]).
+
+
+%% ---
+
+formated_timestamp() ->
+ format_timestamp(os:timestamp()).
+
+format_timestamp(Now) ->
+ N2T = fun(N) -> calendar:now_to_local_time(N) end,
+ format_timestamp(Now, N2T, true).
+
+format_timestamp({_N1, _N2, N3} = N, N2T, true) ->
+ FormatExtra = ".~.2.0w",
+ ArgsExtra = [N3 div 10000],
+ format_timestamp(N, N2T, FormatExtra, ArgsExtra);
+format_timestamp({_N1, _N2, _N3} = N, N2T, false) ->
+ FormatExtra = "",
+ ArgsExtra = [],
+ format_timestamp(N, N2T, FormatExtra, ArgsExtra).
+
+format_timestamp(N, N2T, FormatExtra, ArgsExtra) ->
+ {Date, Time} = N2T(N),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra,
+ [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra),
+ lists:flatten(FormatDate).
+
+
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index dde605b624..702f040434 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -1,21 +1,34 @@
-%%%-------------------------------------------------------------------
-%%% @author Micael Karlberg <[email protected]>
-%%% @copyright (C) 2018, Micael Karlberg
-%%% @doc
-%%%
-%%% @end
-%%% Created : 27 Jun 2018 by Micael Karlberg <[email protected]>
-%%%-------------------------------------------------------------------
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2018-2018. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
-module(socket_server).
--export([start/0]).
+-export([start/0,
+ start_tcp/0,
+ start_udp/0]).
--define(REQ, 0).
--define(REP, 1).
+-define(LIB, socket_lib).
--record(manager, {acceptor, handler_id, handlers}).
+-record(manager, {acceptor, handler_id, handlers}).
-record(acceptor, {socket, manager}).
--record(handler, {socket, manager}).
+-record(handler, {socket, type, manager}).
start() ->
start_tcp().
@@ -23,6 +36,9 @@ start() ->
start_tcp() ->
start(inet, stream, tcp).
+start_udp() ->
+ start(inet, dgram, udp).
+
start(Domain, Type, Proto) ->
put(sname, "starter"),
i("try start manager"),
@@ -51,13 +67,13 @@ manager_stop(Pid, Reason) ->
manager_request(Pid, {stop, Reason}).
manager_request(Pid, Request) ->
- request(manager, Pid, Request).
+ ?LIB:request(manager, Pid, Request).
manager_reply(Pid, Ref, Reply) ->
- reply(manager, Pid, Ref, Reply).
+ ?LIB:reply(manager, Pid, Ref, Reply).
-manager_init(Domain, Type, Proto) ->
+manager_init(Domain, stream = Type, Proto) ->
put(sname, "manager"),
i("try start acceptor"),
case acceptor_start(Domain, Type, Proto) of
@@ -68,8 +84,44 @@ manager_init(Domain, Type, Proto) ->
handlers = []});
{error, Reason} ->
exit({failed_starting_acceptor, Reason})
+ end;
+manager_init(Domain, dgram = Type, Proto) ->
+ put(sname, "manager"),
+ i("try open socket"),
+ case socket:open(Domain, Type, Proto) of
+ {ok, Sock} ->
+ Addr = which_addr(Domain),
+ SA = #{family => Domain,
+ addr => Addr},
+ case socket:bind(Sock, SA) of
+ {ok, _P} ->
+ ok;
+ {error, BReason} ->
+ throw({bind, BReason})
+ end,
+ i("try start handler for"
+ "~n ~p", [case socket:sockname(Sock) of
+ {ok, Name} -> Name;
+ {error, _} = E -> E
+ end]),
+ case handler_start(1, Sock) of
+ {ok, {Pid, MRef}} ->
+ i("handler (~p) started", [Pid]),
+ handler_continue(Pid),
+ manager_loop(#manager{handler_id = 2, % Just in case
+ handlers = [{Pid, MRef, 1}]});
+ {error, SReason} ->
+ e("Failed starting handler: "
+ "~n ~p", [SReason]),
+ exit({failed_start_handler, SReason})
+ end;
+ {error, OReason} ->
+ e("Failed open socket: "
+ "~n ~p", [OReason]),
+ exit({failed_open_socket, OReason})
end.
+
manager_loop(M) ->
receive
{'DOWN', MRef, process, Pid, Reason} ->
@@ -262,7 +314,11 @@ acceptor_loop(#acceptor{socket = LSock} = A) ->
end.
acceptor_handle_accept_success(#acceptor{manager = Manager}, Sock) ->
- i("try start handler"),
+ i("try start handler for peer"
+ "~n ~p", [case socket:peername(Sock) of
+ {ok, Peer} -> Peer;
+ {error, _} = E -> E
+ end]),
case manager_start_handler(Manager, Sock) of
{ok, Pid} ->
i("handler (~p) started - now change 'ownership'", [Pid]),
@@ -309,10 +365,10 @@ handler_continue(Pid) ->
handler_request(Pid, continue).
handler_request(Pid, Request) ->
- request(handler, Pid, Request).
+ ?LIB:request(handler, Pid, Request).
handler_reply(Pid, Ref, Reply) ->
- reply(handler, Pid, Ref, Reply).
+ ?LIB:reply(handler, Pid, Ref, Reply).
handler_init(Manager, ID, Sock) ->
@@ -321,23 +377,30 @@ handler_init(Manager, ID, Sock) ->
Manager ! {handler, self(), ok},
receive
{handler, Pid, Ref, continue} ->
- i("continue"),
+ i("got continue"),
handler_reply(Pid, Ref, ok),
+ {ok, Type} = socket:getopt(Sock, socket, type),
%% socket:setopt(Socket, otp, debug, true),
handler_loop(#handler{manager = Manager,
+ type = Type,
socket = Sock})
end.
-handler_loop(#handler{socket = Socket} = H) ->
- case socket:recv(Socket) of
- {ok, Msg} ->
- i("received ~w bytes of data", [size(Msg)]),
- case dec_msg(Msg) of
+handler_loop(H) ->
+ i("try read message"),
+ case recv(H) of
+ {ok, {Source, Msg}} ->
+ i("received ~w bytes of data~s",
+ [size(Msg), case Source of
+ undefined -> "";
+ _ -> f(" from:~n ~p", [Source])
+ end]),
+ case ?LIB:dec_msg(Msg) of
{request, N, Req} ->
i("received request ~w: "
"~n ~p", [N, Req]),
- Reply = enc_rep_msg(N, "hoppsan"),
- case socket:send(Socket, Reply) of
+ Reply = ?LIB:enc_rep_msg(N, "hoppsan"),
+ case send(H, Reply, Source) of
ok ->
i("successfully sent reply ~w", [N]),
handler_loop(H);
@@ -360,87 +423,99 @@ handler_loop(#handler{socket = Socket} = H) ->
end.
+recv(#handler{socket = Sock, type = stream}) ->
+ case socket:recv(Sock) of
+ {ok, Msg} ->
+ {ok, {undefined, Msg}};
+ {error, _} = ERROR ->
+ ERROR
+ end;
+recv(#handler{socket = Sock, type = dgram}) ->
+ %% ok = socket:setopt(Sock, otp, debug, true),
+ socket:recvfrom(Sock).
+
+
+send(#handler{socket = Sock, type = stream}, Msg, _) ->
+ socket:send(Sock, Msg);
+send(#handler{socket = Sock, type = dgram}, Msg, Dest) ->
+ socket:sendto(Sock, Msg, Dest).
+
+
%% =========================================================================
-enc_req_msg(N, Data) ->
- enc_msg(?REQ, N, Data).
+%% enc_req_msg(N, Data) ->
+%% enc_msg(?REQ, N, Data).
-enc_rep_msg(N, Data) ->
- enc_msg(?REP, N, Data).
+%% enc_rep_msg(N, Data) ->
+%% enc_msg(?REP, N, Data).
-enc_msg(Type, N, Data) when is_list(Data) ->
- enc_msg(Type, N, list_to_binary(Data));
-enc_msg(Type, N, Data)
- when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) ->
- <<Type:32/integer, N:32/integer, Data/binary>>.
+%% enc_msg(Type, N, Data) when is_list(Data) ->
+%% enc_msg(Type, N, list_to_binary(Data));
+%% enc_msg(Type, N, Data)
+%% when is_integer(Type) andalso is_integer(N) andalso is_binary(Data) ->
+%% <<Type:32/integer, N:32/integer, Data/binary>>.
-dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) ->
- {request, N, Data};
-dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) ->
- {reply, N, Data}.
+%% dec_msg(<<?REQ:32/integer, N:32/integer, Data/binary>>) ->
+%% {request, N, Data};
+%% dec_msg(<<?REP:32/integer, N:32/integer, Data/binary>>) ->
+%% {reply, N, Data}.
%% ---
-request(Tag, Pid, Request) ->
- Ref = make_ref(),
- Pid ! {Tag, self(), Ref, Request},
- receive
- {Tag, Pid, Ref, Reply} ->
- Reply
- end.
+%% request(Tag, Pid, Request) ->
+%% Ref = make_ref(),
+%% Pid ! {Tag, self(), Ref, Request},
+%% receive
+%% {Tag, Pid, Ref, Reply} ->
+%% Reply
+%% end.
-reply(Tag, Pid, Ref, Reply) ->
- Pid ! {Tag, self(), Ref, Reply}.
+%% reply(Tag, Pid, Ref, Reply) ->
+%% Pid ! {Tag, self(), Ref, Reply}.
%% ---
-formated_timestamp() ->
- format_timestamp(os:timestamp()).
+%% formated_timestamp() ->
+%% format_timestamp(os:timestamp()).
-format_timestamp(Now) ->
- N2T = fun(N) -> calendar:now_to_local_time(N) end,
- format_timestamp(Now, N2T, true).
+%% format_timestamp(Now) ->
+%% N2T = fun(N) -> calendar:now_to_local_time(N) end,
+%% format_timestamp(Now, N2T, true).
-format_timestamp({_N1, _N2, N3} = N, N2T, true) ->
- FormatExtra = ".~.2.0w",
- ArgsExtra = [N3 div 10000],
- format_timestamp(N, N2T, FormatExtra, ArgsExtra);
-format_timestamp({_N1, _N2, _N3} = N, N2T, false) ->
- FormatExtra = "",
- ArgsExtra = [],
- format_timestamp(N, N2T, FormatExtra, ArgsExtra).
+%% format_timestamp({_N1, _N2, N3} = N, N2T, true) ->
+%% FormatExtra = ".~.2.0w",
+%% ArgsExtra = [N3 div 10000],
+%% format_timestamp(N, N2T, FormatExtra, ArgsExtra);
+%% format_timestamp({_N1, _N2, _N3} = N, N2T, false) ->
+%% FormatExtra = "",
+%% ArgsExtra = [],
+%% format_timestamp(N, N2T, FormatExtra, ArgsExtra).
-format_timestamp(N, N2T, FormatExtra, ArgsExtra) ->
- {Date, Time} = N2T(N),
- {YYYY,MM,DD} = Date,
- {Hour,Min,Sec} = Time,
- FormatDate =
- io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra,
- [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra),
- lists:flatten(FormatDate).
+%% format_timestamp(N, N2T, FormatExtra, ArgsExtra) ->
+%% {Date, Time} = N2T(N),
+%% {YYYY,MM,DD} = Date,
+%% {Hour,Min,Sec} = Time,
+%% FormatDate =
+%% io_lib:format("~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w" ++ FormatExtra,
+%% [YYYY, MM, DD, Hour, Min, Sec] ++ ArgsExtra),
+%% lists:flatten(FormatDate).
%% ---
f(F, A) ->
- lists:flatten(io_lib:format(F, A)).
+ ?LIB:f(F, A).
e(F, A) ->
- p("<ERROR> " ++ F, A).
+ ?LIB:e(F, A).
i(F) ->
- i(F, []).
-i(F, A) ->
- p("*** " ++ F, A).
+ ?LIB:i(F).
-p(F, A) ->
- p(get(sname), F, A).
+i(F, A) ->
+ ?LIB:i(F, A).
-p(SName, F, A) ->
- io:format("[~s,~p][~s] " ++ F ++ "~n",
- [SName,self(),formated_timestamp()|A]).
-