aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2018-06-27 18:37:29 +0200
committerMicael Karlberg <[email protected]>2018-09-18 14:50:18 +0200
commit9b45f4dd2cc8862a183941bb4925223bcec35987 (patch)
tree28ddd97e2dfac789b4d92473aa36d74712f283b6
parentb7b80a767b2938014aa4cfb0c65d4ce5a9019bd5 (diff)
downloadotp-9b45f4dd2cc8862a183941bb4925223bcec35987.tar.gz
otp-9b45f4dd2cc8862a183941bb4925223bcec35987.tar.bz2
otp-9b45f4dd2cc8862a183941bb4925223bcec35987.zip
[test-socket-nif] Add *very primitive* test progs
-rw-r--r--lib/kernel/test/socket_client.erl99
-rw-r--r--lib/kernel/test/socket_server.erl107
2 files changed, 206 insertions, 0 deletions
diff --git a/lib/kernel/test/socket_client.erl b/lib/kernel/test/socket_client.erl
new file mode 100644
index 0000000000..6d74d19442
--- /dev/null
+++ b/lib/kernel/test/socket_client.erl
@@ -0,0 +1,99 @@
+%%%-------------------------------------------------------------------
+%%% @author Micael Karlberg <[email protected]>
+%%% @copyright (C) 2018, Micael Karlberg
+%%% @doc
+%%%
+%%% @end
+%%% Created : 27 Jun 2018 by Micael Karlberg <[email protected]>
+%%%-------------------------------------------------------------------
+-module(client).
+
+-export([start/1]).
+
+start(Port) ->
+ start_tcp(Port).
+
+start_tcp(Port) ->
+ start(inet, stream, tcp, Port).
+
+start(Domain, Type, Proto, Port) ->
+ try do_init(Domain, Type, Proto) of
+ Sock ->
+ connect(Sock, Domain, Port)
+ catch
+ throw:E:P ->
+ e("Failed initiate: "
+ "~n Error: ~p"
+ "~n Path: ~p", [E, P])
+ end.
+
+do_init(Domain, Type, Proto) ->
+ i("try (socket) open"),
+ Sock = case socket:open(Domain, Type, Proto) of
+ {ok, S} ->
+ S;
+ {error, OReason} ->
+ throw({open, OReason})
+ end,
+ i("try (socket) bind"),
+ case socket:bind(Sock, any) of
+ {ok, _P} ->
+ Sock;
+ {error, BReason} ->
+ throw({bind, BReason})
+ end.
+
+which_addr(Domain) ->
+ Iflist = case inet:getifaddrs() of
+ {ok, IFL} ->
+ IFL;
+ {error, Reason} ->
+ throw({inet,getifaddrs,Reason})
+ end,
+ which_addr(Domain, Iflist).
+
+
+connect(Sock, Domain, Port) ->
+ Addr = which_addr(Domain),
+ SA = #{family => Domain,
+ addr => Addr,
+ port => Port},
+ i("try (socket) connect to ~p", [SA]),
+ case socket:connect(Sock, SA) of
+ ok ->
+ i("connected"),
+ ok;
+ {error, Reason} ->
+ e("connect failure: "
+ "~n ~p", [Reason]),
+ exit({connect, Reason})
+ end.
+
+
+which_addr(_Domain, []) ->
+ throw(no_address);
+which_addr(Domain, [{Name, IFO}|_IFL]) when (Name =/= "lo") ->
+ which_addr2(Domain, IFO);
+which_addr(Domain, [_|IFL]) ->
+ which_addr(Domain, IFL).
+
+which_addr2(inet = _Domain, [{addr, Addr}|_IFO]) when (size(Addr) =:= 4) ->
+ Addr;
+which_addr2(inet6 = _Domain, [{addr, Addr}|_IFO]) when (size(Addr) =:= 8) ->
+ Addr;
+which_addr2(Domain, [_|IFO]) ->
+ which_addr2(Domain, IFO).
+
+
+
+e(F, A) ->
+ p("<ERROR> " ++ F, A).
+
+i(F) ->
+ i(F, []).
+i(F, A) ->
+ p("*** " ++ F, A).
+
+p(F, A) ->
+ io:format("[client] " ++ F ++ "~n", A).
+
diff --git a/lib/kernel/test/socket_server.erl b/lib/kernel/test/socket_server.erl
new file mode 100644
index 0000000000..039998ba92
--- /dev/null
+++ b/lib/kernel/test/socket_server.erl
@@ -0,0 +1,107 @@
+%%%-------------------------------------------------------------------
+%%% @author Micael Karlberg <[email protected]>
+%%% @copyright (C) 2018, Micael Karlberg
+%%% @doc
+%%%
+%%% @end
+%%% Created : 27 Jun 2018 by Micael Karlberg <[email protected]>
+%%%-------------------------------------------------------------------
+-module(server).
+
+-export([start/0]).
+
+start() ->
+ start_tcp().
+
+start_tcp() ->
+ start(inet, stream, tcp).
+
+start(Domain, Type, Proto) ->
+ try do_init(Domain, Type, Proto) of
+ Sock ->
+ accept_loop(Sock)
+ catch
+ throw:E:P ->
+ e("Failed initiate: "
+ "~n Error: ~p"
+ "~n Path: ~p", [E, P])
+ end.
+
+do_init(Domain, Type, Proto) ->
+ i("try (socket) open"),
+ Sock = case socket:open(Domain, Type, Proto) of
+ {ok, S} ->
+ S;
+ {error, OReason} ->
+ throw({open, OReason})
+ end,
+ i("opened - now try find (local) address"),
+ Addr = which_addr(Domain),
+ SA = #{family => Domain,
+ addr => Addr},
+ i("addr ~p - now try (socket) bind", [Addr]),
+ Port = case socket:bind(Sock, SA) of
+ {ok, P} ->
+ P;
+ {error, BReason} ->
+ throw({bind, BReason})
+ end,
+ i("bound to ~w - now try (socket) listen", [Port]),
+ case socket:listen(Sock) of
+ ok ->
+ Sock;
+ {error, LReason} ->
+ throw({listen, LReason})
+ end.
+
+which_addr(Domain) ->
+ Iflist = case inet:getifaddrs() of
+ {ok, IFL} ->
+ IFL;
+ {error, Reason} ->
+ throw({inet,getifaddrs,Reason})
+ end,
+ which_addr(Domain, Iflist).
+
+which_addr(_Domain, []) ->
+ throw(no_address);
+which_addr(Domain, [{Name, IFO}|_IFL]) when (Name =/= "lo") ->
+ which_addr2(Domain, IFO);
+which_addr(Domain, [_|IFL]) ->
+ which_addr(Domain, IFL).
+
+which_addr2(inet = _Domain, [{addr, Addr}|_IFO]) when (size(Addr) =:= 4) ->
+ Addr;
+which_addr2(inet6 = _Domain, [{addr, Addr}|_IFO]) when (size(Addr) =:= 8) ->
+ Addr;
+which_addr2(Domain, [_|IFO]) ->
+ which_addr2(Domain, IFO).
+
+
+accept_loop(LSock) ->
+ accept_loop(LSock, []).
+
+accept_loop(LSock, Socks) ->
+ i("try accept"),
+ case socket:accept(LSock, infinity) of
+ {ok, Sock} ->
+ i("accepted: ~p", [Sock]),
+ accept_loop(LSock, [Sock|Socks]);
+ {error, Reason} ->
+ e("accept failure: "
+ "~n ~p", [Reason]),
+ exit({accept, Reason})
+ end.
+
+
+e(F, A) ->
+ p("<ERROR> " ++ F, A).
+
+i(F) ->
+ i(F, []).
+i(F, A) ->
+ p("*** " ++ F, A).
+
+p(F, A) ->
+ io:format("[server] " ++ F ++ "~n", A).
+