aboutsummaryrefslogtreecommitdiffstats
path: root/lib/kernel/test/socket_server.erl
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-06-29 18:23:55 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit24be0729fe3a1ccfd5f0713b565463d6557d8aa7 (patch)
tree2243a51ada05a3ddeacd443ed6e49262cf79766c /lib/kernel/test/socket_server.erl
parentb09136301525b0717e897ec0864c3d2ea7708758 (diff)
downloadotp-24be0729fe3a1ccfd5f0713b565463d6557d8aa7.tar.gz
otp-24be0729fe3a1ccfd5f0713b565463d6557d8aa7.tar.bz2
otp-24be0729fe3a1ccfd5f0713b565463d6557d8aa7.zip
[socket-nif] Fixed (stream) recv
Fixed handling of closed in the recv function. We still need to properly handle when we get 0 bytes of data for other types ock sockets then stream (its valid for dgram for instance). OTP-14831
Diffstat (limited to 'lib/kernel/test/socket_server.erl')
-rw-r--r--lib/kernel/test/socket_server.erl105
1 files changed, 88 insertions, 17 deletions
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
index 0effc7c0ff..64bd6396e4 100644
--- a/lib/kernel/test/socket_server.erl
+++ b/lib/kernel/test/socket_server.erl
@@ -10,6 +10,9 @@
-export([start/0]).
+-define(REQ, 0).
+-define(REP, 1).
+
-record(handler, {socket, parent}).
start() ->
@@ -82,14 +85,17 @@ which_addr2(Domain, [_|IFO]) ->
accept_loop(LSock) ->
- put(sname, "accept-loop"),
+ put(sname, "acceptor"),
accept_loop(LSock, []).
accept_loop(LSock, Handlers) ->
i("try accept"),
case socket:accept(LSock, infinity) of
{ok, Sock} ->
- i("accepted: ~p", [Sock]),
+ i("accepted: "
+ "~n ~p"
+ "~nwhen"
+ "~n ~p", [Sock, socket:info()]),
case handle_accept_success(Sock) of
{ok, Handler} ->
accept_loop(LSock, [Handler|Handlers]);
@@ -127,6 +133,7 @@ handler_init(Parent, Socket) ->
put(sname, "handler"),
receive
{handler, Parent, continue} ->
+ socket:setopt(Socket, otp, debug, true),
handler_loop(#handler{parent = Parent,
socket = Socket})
end.
@@ -135,27 +142,90 @@ handler_continue(Handler) ->
Handler ! {handler, self(), continue}.
handler_loop(#handler{socket = Socket} = H) ->
- case socket:read(Socket, 0) of
- {ok, <<0:32, N:32, ReqData/binary>>} ->
- i("received request ~w: "
- "~n ~p", [N, ReqData]),
- Reply = <<1:32, N:32, ReqData/binary>>,
- case socket:send(Socket, Reply) of
- ok ->
- i("successfully sent reply ~w", [N]),
- handler_loop(H);
- {error, SReason} ->
- e("failed sending reply ~w:"
- "~n ~p", [N, SReason]),
- exit({failed_sending_reply, SReason})
+ case socket:recv(Socket, 0) of
+ {ok, Msg} when (size(Msg) =:= 0) ->
+ i("received empty msg - hickup? - try again", []),
+ handler_loop(H);
+ {ok, Msg} ->
+ i("received ~w bytes of data", [size(Msg)]),
+ case 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
+ ok ->
+ i("successfully sent reply ~w", [N]),
+ handler_loop(H);
+ {error, SReason} ->
+ e("failed sending reply ~w:"
+ "~n ~p", [N, SReason]),
+ exit({failed_sending_reply, SReason})
+ end
end;
+
+ {error, closed} ->
+ i("closed when"
+ "~n ~p", [socket:info()]),
+ exit(normal);
+
{error, RReason} ->
e("failed reading request: "
"~n ~p", [RReason]),
- exit({failed_sending_reply, RReason})
+ exit({failed_reading_request, RReason})
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}.
+
+
+%% ---
+
+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).
+
+
+%% ---
+
e(F, A) ->
p("<ERROR> " ++ F, A).
@@ -168,5 +238,6 @@ p(F, A) ->
p(get(sname), F, A).
p(SName, F, A) ->
- io:format("[server,~s] " ++ F ++ "~n", [SName|A]).
+ io:format("[server:~s,~p][~s] " ++ F ++ "~n",
+ [SName,self(),formated_timestamp()|A]).