From 0b56a98366fc152c0fa5d5398220ac31866114d5 Mon Sep 17 00:00:00 2001 From: Micael Karlberg Date: Fri, 28 Sep 2018 18:34:45 +0200 Subject: [socket-nif|doc] Cleanup and fixed setopt doc Removed some cruft. Also tried, without success, to fix the build issue ("Error file: cannot find module exporting type"). It may be because of a spec-file issue. Finally fixed the setopt doc. It did not have a seperate clause for clause 8 (the fallback clause that takes level and key as integer). --- erts/doc/src/net.xml | 4 +- erts/doc/src/socket.xml | 272 ++++-------------------------------------------- 2 files changed, 23 insertions(+), 253 deletions(-) diff --git a/erts/doc/src/net.xml b/erts/doc/src/net.xml index c022fee4f7..e0c3b4ec73 100644 --- a/erts/doc/src/net.xml +++ b/erts/doc/src/net.xml @@ -75,7 +75,7 @@

Address-to-name translation in a protocol-independant manner.

This function is the inverse of - getaddrinfo. + getaddrinfo. It converts a socket address to a corresponding host and service.

@@ -89,7 +89,7 @@

Network address and service translation.

This function is the inverse of - getnameinfo. + getnameinfo. It converts host and service to a corresponding socket address.

One of the Host and Service may be undefined but not both.

diff --git a/erts/doc/src/socket.xml b/erts/doc/src/socket.xml index e2fd0adc8f..af7e0ca9c1 100644 --- a/erts/doc/src/socket.xml +++ b/erts/doc/src/socket.xml @@ -245,7 +245,8 @@ doing a close does not guarantee that any data sent is delivered to the recipient before the close is detected at the remote side.

One way to handle this is to use the - shutdown function + shutdown + function (socket:shutdown(Socket, write)) to signal that no more data is to be sent and then wait for the read side of the socket to be closed.

@@ -281,49 +282,6 @@ even if "we" support an option, that does not mean that the underlying OS does.

-
@@ -501,6 +459,24 @@ + Set options on a socket. + +

Set options on a socket.

+

What properties are valid depend both on Level and on + what kind of socket it is (domain, type and + protocol).

+ +

Not all options are valid on all platforms. That is, + even if "we" support an option, that does not mean that the + underlying OS does.

+ +

Sockets are set 'non-blocking' when created, so this option + is *not* available (as it would adversely effect the Erlang VM + to set a socket 'blocking').

+
+ + + Set options on a socket. @@ -539,213 +515,7 @@
Examples -

TBD: Need to implement a receiver process in order to be able to - implement active!

-

x_tcp.erl:

- -listen(Addr, Port) -> - try - begin - Socket = case socket:open(inet, stream, tcp) of - {ok, Socket} -> - Socket; - {error, _} = OERROR -> - throw(OERROR) - end, - SockAddr = #in4_sockaddr{port = Port, - addr = Addr}, - ok = case socket:bind(Socket, SockAddr) of - ok -> - ok; - {error, _} = BERROR -> - throw(BERROR) - end, - case socket:listen(Socket, 10) of - ok -> - {ok, Socket}; - {error, _} = LERROR -> - throw(LERROR) - end - end - catch - throw:ERROR -> - ERROR -end. - - - -connect(Addr, Port) -> - try - begin - Socket = case socket:open(inet, stream, tcp) of - {ok, Socket} -> - Socket; - {error, _} = OERROR -> - throw(OERROR) - end, - BSockAddr = #in4_sockaddr{port = 0, - addr = any}, - ok = case socket:bind(Socket, BSockAddr) of - ok -> - ok; - {error, _} = BERROR -> - throw(BERROR) - end, - CSockAddr = #in4_sockaddr{port = Port, - addr = Addr}, - Socket = case socket:connect(Socket, CSockAddr) of - {ok, Sock} -> - Sock; - {error, _} = CERROR -> - throw(CERROR) - end, - case start_receiver(Socket) of - {ok, Pid} -> - ok = socket:ts_add(Socket, receiver, Pid), - {ok, Socket}; - {error, _} = RERROR -> - socket:close(Socket), - throw(RERROR) - end - end - catch - throw:ERROR -> - ERROR -end. - - - -accept(LSocket) -> - case socket:accept(LSocket) of - {ok, Socket} -> - case start_receiver(Socket) of - {ok, Pid} -> - ok = socket:ts_add(Socket, receiver, Pid), - {ok, Socket}; - {error, _} = RERROR -> - socket:close(Socket), - throw(RERROR) - end, - {error, _} = AERROR -> - AERROR - end. - - - -send(Socket, Data) -> - socket:send(Socket, Data). - - - -setopt(Socket, controlling_process = Item, Pid) when is_pid(Pid) -> - case socket:setopt(Socket, otp, Item, Pid) of - ok -> - {ok, Receiver} = socket:ts_get(Socket, receiver), - update_receiver(Receiver, {controlling_process, Pid), - ok; - {error, _} = ERROR -> - ERROR - end; -setopt(Socket, active, Active) -> - {ok, Receiver} = socket:ts_get(Socket, receiver), - receiver_active(Receiver, Active), - ok; -%% This is just to indicate that there will be more options -%% that needs to be handled -setopt(Socket, Item, Pid) when is_pid(Pid) -> - socket:setopt(Socket, which_level(Item), Item, Pid). - - -

The receiver process:

- -start_receiver(Socket) -> - CtrlProc = self(), - Ref = make_ref(), - Receiver = proc_lib:spawn_link(fun() -> receiver_init(CtrlProc, Ref) end), - receive - {?MODULE, started, Ref} -> - Receiver ! {?MODULE, receiver, Ref, Sock, true}, - unlink(Receiver), - {ok, Receiver}; - {'EXIT', Receiver, Reason} -> - {error, Reason} - end. - -receiver_active(Receiver, Active) - when (Active =:= false) orelse - (Active =:= true) orelse - (Active =:= once) orelse - is_integer(Active) -> - Receiver ! {?MODULE, active, What}. - -receiver_update(Receiver, What) -> - Ref = make_ref(), - Receiver ! {?MODULE, receiver_update, Ref, What}, - receive - {?MODULE, receiver_upadate, Ref, Result} -> - Result - end. - --record(receiver, {sock :: socket:socket(), - ctrl :: pid(), - num_packages :: infinity | non_neg_ineteger()}). - -receiver_init(Pid, Ref) -> - receive - {?MODULE, receiver, Ref, stop} -> - i("received stop"), - exit(normal); - - {?MODULE, receiver, Ref, Sock, InitialMode} -> - i("received socket: ~p", [Sock]), - NumPackages = mode2pkgcount(InitialMode), - receiver(#receiver{sock = Sock, ctrl = Pid}) - end. - -mode2pkgcount(true) -> - infinity; -mode2pkgcount(false) -> - 0; -mode2pkgcount(N) when is_integer(N) andalso (N >= 0) -> - N. - -receiver(#receiver{num_packages = 0} = State) -> - receive - {?MODULE, active, false} -> - receiver(State); - {?MODULE, active, true} -> - receiver(State#receiver{num_packages = infinity}); - {?MODULE, active, once} -> - receiver(State#receiver{num_packages = 1}); - {?MODULE, active, N} when (N > 0) -> - receiver(State#receiver{num_packages = N}) - end; -receiver(#receiver{num_packages = N, sock = Sock, ctrl = Pid} = State) -> - case socket:recv(Sock, 0) of - {ok, Package} when size(Package) > 0 -> - Pid ! {tcp, Sock, Packege}, - case next_active(N) of - 0 -> - Pid ! {tcp_passive, Sock}, - receiver(State#{num_packages = 0}); - NextN -> - receiver(State#{num_packages = NextN}) - end; - {ok, Package} when size(Package) =:= 0 -> - receiver(State); - - {error, closed} -> - i("closed"), - Pid ! {tcp_closed, Sock}, - exit(normal); - - {error, Reason} -> - i("error: ~p", [Reason]), - Pid ! {tcp_error, Sock, Reason}, - exit(normal) - end. - - +

TBD

-- cgit v1.2.3