12 Socket Usage
12.1 Introduction
The socket interface (module) is basically an "thin" layer on top of the OS socket interface. It is assumed that, unless you have special needs, gen_[tcp|udp|sctp] should be sufficent (when they become available).
Note that just because we have a documented and described option, it does not mean that the OS supports it. So its recommended that the user reads the platform specific documentation for the option used.
Asynchronous calls
Some functions allow for an asynchronous call (accept/2, connect/3, recv/3,4, recvfrom/3,4, recvmsg/2,3,5, send/3,4, sendmsg/3,4 and sendto/4,5). This is achieved by setting the Timeout argument to nowait. For instance, if calling the recv/3 function with Timeout set to nowait (i.e. recv(Sock, 0, nowait)) when there is actually nothing to read, it will return with {select, SelectInfo} (SelectInfo contains the SelectRef). When data eventually arrives a 'select message' will be sent to the caller:
- {'$socket', socket(), select, SelectRef}
The caller can then make another call to the recv function and now expect data.
The user must also be prepared to receive an abort message:
- {'$socket', socket(), abort, Info}
If the operation is aborted for whatever reason (e.g. if the socket is closed "by someone else"). The Info part contains the abort reason (in this case that the socket has been closed Info = {SelectRef, closed}).
Note that all other users are locked out until the 'current user' has called the function (recv in this case). So either immediately call the function or cancel.
The general form of the 'socket' message is:
- {'$socket', Sock :: socket(), Tag :: atom(), Info :: term()}
Where the format of Info is a function of Tag:
Tag | Info value type |
select | select_ref() |
abort | {select_ref(), Reason :: term()} |
The select_ref() is the same as was received in the SelectInfo.
12.2 Socket Options
Options for level otp:
Option Name | Value Type | Set | Get | Other Requirements and comments |
assoc_id | integer() | no | yes | type = seqpacket, protocol = sctp, is an association |
debug | boolean() | yes | yes | none |
iow | boolean() | yes | yes | none |
controlling_process | pid() | yes | yes | none |
rcvbuf | default | pos_integer() | {pos_integer(), pos_ineteger()} | yes | yes | 'default' only valid for set. The tuple form is only valid for type 'stream' and protocol 'tcp'. |
rcvctrlbuf | default | pos_integer() | yes | yes | default only valid for set |
sndctrlbuf | default | pos_integer() | yes | yes | default only valid for set |
fd | integer() | no | yes | none |
Options for level socket:
Option Name | Value Type | Set | Get | Other Requirements and comments |
acceptconn | boolean() | no | yes | none |
bindtodevice | string() | yes | yes | Before Linux 3.8, this socket option could be set, but not get. Only works for some socket types (e.g. inet). If empty value is set, the binding is removed. |
broadcast | boolean() | yes | yes | type = dgram |
debug | integer() | yes | yes | may require admin capability |
domain | domain() | no | yes | Not on FreeBSD (for instance) |
dontroute | boolean() | yes | yes | none |
keepalive | boolean() | yes | yes | none |
linger | abort | linger() | yes | yes | none |
oobinline | boolean() | yes | yes | none |
peek_off | integer() | yes | yes | domain = local (unix) |
priority | integer() | yes | yes | none |
protocol | protocol() | no | yes | Not on (some) Darwin (for instance) |
rcvbuf | non_neg_integer() | yes | yes | none |
rcvlowat | non_neg_integer() | yes | yes | none |
rcvtimeo | timeval() | yes | yes | none |
reuseaddr | boolean() | yes | yes | none |
reuseport | boolean() | yes | yes | domain = inet | inet6 |
sndbuf | non_neg_integer() | yes | yes | none |
sndlowat | non_neg_integer() | yes | yes | not changeable on Linux |
sndtimeo | timeval() | yes | yes | none |
timestamp | boolean() | yes | yes | none |
type | type() | no | yes | none |
Options for level ip:
Option Name | Value Type | Set | Get | Other Requirements and comments |
add_membership | ip_mreq() | yes | no | none |
add_source_membership | ip_mreq_source() | yes | no | none |
block_source | ip_mreq_source() | yes | no | none |
drop_membership | ip_mreq() | yes | no | none |
drop_source_membership | ip_mreq_source() | yes | no | none |
freebind | boolean() | yes | yes | none |
hdrincl | boolean() | yes | yes | type = raw |
minttl | integer() | yes | yes | type = raw |
msfilter | null | ip_msfilter() | yes | no | none |
mtu | integer() | no | yes | type = raw |
mtu_discover | ip_pmtudisc() | yes | yes | none |
multicast_all | boolean() | yes | yes | none |
multicast_if | any | ip4_address() | yes | yes | none |
multicast_loop | boolean() | yes | yes | none |
multicast_ttl | uint8() | yes | yes | none |
nodefrag | boolean() | yes | yes | type = raw |
pktinfo | boolean() | yes | yes | type = dgram |
recvdstaddr | boolean() | yes | yes | type = dgram |
recverr | boolean() | yes | yes | none |
recvif | boolean() | yes | yes | type = dgram | raw |
recvopts | boolean() | yes | yes | type =/= stream |
recvorigdstaddr | boolean() | yes | yes | none |
recvttl | boolean() | yes | yes | type =/= stream |
retopts | boolean() | yes | yes | type =/= stream |
router_alert | integer() | yes | yes | type = raw |
sendsrcaddr | boolean() | yes | yes | none |
tos | ip_tos() | yes | yes | some high-priority levels may require superuser capability |
transparent | boolean() | yes | yes | requires admin capability |
ttl | integer() | yes | yes | none |
unblock_source | ip_mreq_source() | yes | no | none |
Options for level ipv6:
Option Name | Value Type | Set | Get | Other Requirements and comments |
addrform | inet | yes | no | allowed only for IPv6 sockets that are connected and bound to a v4-mapped-on-v6 address |
add_membership | ipv6_mreq() | yes | no | none |
authhdr | boolean() | yes | yes | type = dgram | raw, obsolete? |
drop_membership | ipv6_mreq() | yes | no | none |
dstopts | boolean() | yes | yes | type = dgram | raw, requires superuser privileges to update |
flowinfo | boolean() | yes | yes | type = dgram | raw, requires superuser privileges to update |
hoplimit | boolean() | yes | yes | type = dgram | raw, requires superuser privileges to update |
hopopts | boolean() | yes | yes | type = dgram | raw, requires superuser privileges to update |
mtu | boolean() | yes | yes | Get: Only after the socket has been connected |
mtu_discover | ipv6_pmtudisc() | yes | yes | none |
multicast_hops | default | uint8() | yes | yes | none |
multicast_if | integer() | yes | yes | type = dgram | raw |
multicast_loop | boolean() | yes | yes | none |
recverr | boolean() | yes | yes | none |
recvpktinfo | pktinfo | boolean() | yes | yes | type = dgram | raw |
router_alert | integer() | yes | yes | type = raw |
rthdr | boolean() | yes | yes | type = dgram | raw, requires superuser privileges to update |
unicast_hops | default | uint8() | yes | yes | none |
v6only | boolean() | yes | no | none |
Options for level tcp:
Option Name | Value Type | Set | Get | Other Requirements and comments |
congestion | string() | yes | yes | none |
maxseg | integer() | yes | yes | none |
nodelay | boolean() | yes | yes | none |
Options for level udp:
Option Name | Value Type | Set | Get | Other Requirements and comments |
cork | boolean() | yes | yes | none |
Options for level sctp:
Option Name | Value Type | Set | Get | Other Requirements and comments |
associnfo | sctp_assocparams() | yes | yes | none |
autoclose | non_neg_integer() | yes | yes | none |
disable_fragments | boolean() | yes | yes | none |
events | sctp_event_subscribe() | yes | no | none |
initmsg | sctp_initmsg() | yes | yes | none |
maxseg | non_neg_integer() | yes | yes | none |
nodelay | boolean() | yes | yes | none |
rtoinfo | sctp_rtoinfo() | yes | yes | none |