The
This module was written for one-to-many style sockets
(type
Record definitions for the
-include_lib("kernel/include/inet_sctp.hrl").
These record definitions use the "new" spelling 'adaptation', not the deprecated 'adaption', regardless of which spelling the underlying C API uses.
An opaque term returned in for example #sctp_paddr_change{}
that identifies an association for an SCTP socket. The term
is opaque except for the special value
One of the
Socket identifier returned from
Abnormally terminates the association given by
Completely closes the socket and all associations on it. The unsent
data is flushed as in
Same as
Establishes a new association for the socket
WARNING:Using a value of
#sctp_assoc_change{ state = atom(), error = atom(), outbound_streams = integer(), inbound_streams = integer(), assoc_id = assoc_id() }
The number of outbound and inbound streams can be set by
giving an
connect(Socket , Ip,Port , [{sctp_initmsg,#sctp_initmsg{num_ostreams=OutStreams, max_instreams=MaxInStreams}}])
All options
The returned
The following values of
All other states do not normally occur in the output from
Same as
Initiates a new association for the socket
The fundamental difference between this API
and
The parameters are as described
in
The timer associated with
Assigns a new controlling process
Gracefully terminates the association given by
Sets up a socket to listen on the IP address and port number it is bound to.
For type
For type
Creates an SCTP socket and binds it to the local addresses
specified by all
Other options are:
Set up the socket for IPv6.
Set up the socket for IPv4. This is the default.
A default set of socket
Branch off an existing association
The existing association argument
Receives the
The actual
#sctp_paddr_change{ addr = {ip_address(),port()}, state = atom(), error = integer(), assoc_id = assoc_id() }
Indicates change of the status of the peer's IP address given by
In case of an error (e.g.
#sctp_send_failed{ flags = true | false, error = integer(), info = #sctp_sndrcvinfo{}, assoc_id = assoc_id() data = binary() }
The sender may receive this event if a send operation fails.
The
In the current implementation of the Erlang/SCTP binding,
this Event is internally converted into an
#sctp_adaptation_event{ adaptation_ind = integer(), assoc_id = assoc_id() }
Delivered when a peer sends an Adaptation Layer Indication
parameter (configured through the option
#sctp_pdapi_event{ indication = sctp_partial_delivery_aborted, assoc_id = assoc_id() }
A partial delivery failure. In the current implementation of
the Erlang/SCTP binding, this Event is internally converted
into an
Sends the
Sends
Translates an SCTP error number from for example
The set of admissible SCTP socket options is by construction
orthogonal to the sets of TCP, UDP and generic INET options:
only those options which are explicitly listed below are allowed
for SCTP sockets. Options can be set on the socket using
Determines the type of data returned from
If
If
NB: This can cause the message queue to overflow, as there is no way to throttle the sender in this case (no flow control!).
If
Sets the Type-Of-Service field on the IP datagrams being sent, to the given value, which effectively determines a prioritization policy for the outbound packets. The acceptable values are system-dependent. TODO: we do not provide symbolic names for these values yet.
A protocol-independent equivalent of
By default
By default
The size, in bytes, of the *kernel* send buffer for this socket.
Sending errors would occur for datagrams larger than
The size, in bytes, of the *kernel* recv buffer for this socket.
Sending errors would occur for datagrams larger than
#sctp_rtoinfo{ assoc_id = assoc_id(), initial = integer(), max = integer(), min = integer() }
Determines re-transmission time-out parameters, in milliseconds,
for the association(s) given by
#sctp_assocparams{ assoc_id = assoc_id(), asocmaxrxt = integer(), number_peer_destinations = integer(), peer_rwnd = integer(), local_rwnd = integer(), cookie_life = integer() }
Determines association parameters for the association(s) given by
#sctp_initmsg{ num_ostreams = integer(), max_instreams = integer(), max_attempts = integer(), max_init_timeo = integer() }
Determines the default parameters which this socket attempts
to negotiate with its peer while establishing an association with it.
Should be set after
Determines the time (in seconds) after which an idle association is
automatically closed.
Turns on|off the Nagle algorithm for merging small packets into larger ones (which improves throughput at the expense of latency).
If
Turns on|off automatic mapping of IPv4 addresses into IPv6 ones (if the socket address family is AF_INET6).
Determines the maximum chunk size if message fragmentation is used.
If
#sctp_prim{ assoc_id = assoc_id(), addr = {IP, Port} } IP = ip_address() Port = port_number()
For the association given by
#sctp_setpeerprim{ assoc_id = assoc_id(), addr = {IP, Port} } IP = ip_address() Port = port_number()
When set, informs the peer that it should use
#sctp_setadaptation{ adaptation_ind = integer() }
When set, requests that the local endpoint uses the value given by
#sctp_paddrparams{ assoc_id = assoc_id(), address = {IP, Port}, hbinterval = integer(), pathmaxrxt = integer(), pathmtu = integer(), sackdelay = integer(), flags = list() } IP = ip_address() Port = port_number()
This option determines various per-address parameters for
the association given by
#sctp_sndrcvinfo{ stream = integer(), ssn = integer(), flags = list(), ppid = integer(), context = integer(), timetolive = integer(), tsn = integer(), cumtsn = integer(), assoc_id = assoc_id() }
Other fields are rarely used. See
#sctp_event_subscribe{ data_io_event = true | false, association_event = true | false, address_event = true | false, send_failure_event = true | false, peer_error_event = true | false, shutdown_event = true | false, partial_delivery_event = true | false, adaptation_layer_event = true | false }
This option determines which
#sctp_assoc_value{ assoc_id = assoc_id(), assoc_value = integer() }
Rarely used. Determines the ACK time
(given by
#sctp_status{ assoc_id = assoc_id(), state = atom(), rwnd = integer(), unackdata = integer(), penddata = integer(), instrms = integer(), outstrms = integer(), fragmentation_point = integer(), primary = #sctp_paddrinfo{} }
This option is read-only. It determines the status of
the SCTP association given by
The semantics of other fields is the following:
#sctp_paddrinfo{ assoc_id = assoc_id(), address = {IP, Port}, state = inactive | active, cwnd = integer(), srtt = integer(), rto = integer(), mtu = integer() } IP = ip_address() Port = port_number()
This option is read-only. It determines the parameters specific to
the peer's address given by
Example of an Erlang SCTP Server which receives SCTP messages and prints them on the standard output:
-module(sctp_server). -export([server/0,server/1,server/2]). -include_lib("kernel/include/inet.hrl"). -include_lib("kernel/include/inet_sctp.hrl"). server() -> server(any, 2006). server([Host,Port]) when is_list(Host), is_list(Port) -> {ok, #hostent{h_addr_list = [IP|_]}} = inet:gethostbyname(Host), io:format("~w -> ~w~n", [Host, IP]), server([IP, list_to_integer(Port)]). server(IP, Port) when is_tuple(IP) orelse IP == any orelse IP == loopback, is_integer(Port) -> {ok,S} = gen_sctp:open(Port, [{recbuf,65536}, {ip,IP}]), io:format("Listening on ~w:~w. ~w~n", [IP,Port,S]), ok = gen_sctp:listen(S, true), server_loop(S). server_loop(S) -> case gen_sctp:recv(S) of {error, Error} -> io:format("SCTP RECV ERROR: ~p~n", [Error]); Data -> io:format("Received: ~p~n", [Data]) end, server_loop(S).
Example of an Erlang SCTP Client which interacts with the above Server.
Note that in this example, the Client creates an association with
the Server with 5 outbound streams. For this reason, sending of
"Test 0" over Stream 0 succeeds, but sending of "Test 5"
over Stream 5 fails. The client then
-module(sctp_client). -export([client/0, client/1, client/2]). -include_lib("kernel/include/inet.hrl"). -include_lib("kernel/include/inet_sctp.hrl"). client() -> client([localhost]). client([Host]) -> client(Host, 2006); client([Host, Port]) when is_list(Host), is_list(Port) -> client(Host,list_to_integer(Port)), init:stop(). client(Host, Port) when is_integer(Port) -> {ok,S} = gen_sctp:open(), {ok,Assoc} = gen_sctp:connect (S, Host, Port, [{sctp_initmsg,#sctp_initmsg{num_ostreams=5}}]), io:format("Connection Successful, Assoc=~p~n", [Assoc]), io:write(gen_sctp:send(S, Assoc, 0, <<"Test 0">>)), io:nl(), timer:sleep(10000), io:write(gen_sctp:send(S, Assoc, 5, <<"Test 5">>)), io:nl(), timer:sleep(10000), io:write(gen_sctp:abort(S, Assoc)), io:nl(), timer:sleep(1000), gen_sctp:close(S).
A very simple Erlang SCTP Client which uses the connect_init API.
-module(ex3). -export([client/4]). -include_lib("kernel/include/inet.hrl"). -include_lib("kernel/include/inet_sctp.hrl"). client(Peer1, Port1, Peer2, Port2) when is_tuple(Peer1), is_integer(Port1), is_tuple(Peer2), is_integer(Port2) -> {ok,S} = gen_sctp:open(), SctpInitMsgOpt = {sctp_initmsg,#sctp_initmsg{num_ostreams=5}}, ActiveOpt = {active, true}, Opts = [SctpInitMsgOpt, ActiveOpt], ok = gen_sctp:connect(S, Peer1, Port1, Opts), ok = gen_sctp:connect(S, Peer2, Port2, Opts), io:format("Connections initiated~n", []), client_loop(S, Peer1, Port1, undefined, Peer2, Port2, undefined). client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) -> receive {sctp, S, Peer1, Port1, {_Anc, SAC}} when is_record(SAC, sctp_assoc_change), AssocId1 == undefined -> io:format("Association 1 connect result: ~p. AssocId: ~p~n", [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]), client_loop(S, Peer1, Port1, SAC#sctp_assoc_change.assoc_id, Peer2, Port2, AssocId2); {sctp, S, Peer2, Port2, {_Anc, SAC}} when is_record(SAC, sctp_assoc_change), AssocId2 == undefined -> io:format("Association 2 connect result: ~p. AssocId: ~p~n", [SAC#sctp_assoc_change.state, SAC#sctp_assoc_change.assoc_id]), client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, SAC#sctp_assoc_change.assoc_id); {sctp, S, Peer1, Port1, Data} -> io:format("Association 1: received ~p~n", [Data]), client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2); {sctp, S, Peer2, Port2, Data} -> io:format("Association 2: received ~p~n", [Data]), client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2); Other -> io:format("Other ~p~n", [Other]), client_loop(S, Peer1, Port1, AssocId1, Peer2, Port2, AssocId2) after 5000 -> ok end.