---
name: "socket"
section: "3erl"
platform: "linux"
package: "erlang-manpages"
version: "1:25.2.3+dfsg-1+deb12u4"
release: "Debian 12 (Bookworm)"
platforms: ["linux"]
url: "https://new.carta.tech/socket/3erl"
---

# socket(3erl)

Socket interface.

## NAME

socket - Socket interface.

## DESCRIPTION

This module provides an API for network socket. Functions are provided to create, delete and manipulate the sockets as well as sending and receiving data on them.

The intent is that it shall be as "close as possible" to the OS level socket interface. The only significant addition is that some of the functions, e.g. *recv/3*, have a time-out argument.

**Note:**

Some functions allow for an *asynchronous*  call. This is achieved by setting the *Timeout* argument to *nowait*. For instance, if calling the *recv/3* function with Timeout set to *nowait* (*recv(Sock, 0, nowait)*) when there is actually nothing to read, it will return with *{select,*  *SelectInfo}* (*SelectInfo* contains the SelectHandle). When data eventually arrives a 'select' message will be sent to the caller:

- **:**

  *{'$socket', socket(), select, SelectHandle}*

The caller can now call the *recv* function again and probably expect data (it is really up to the OS network protocol implementation).

Note that all other users are *locked out* until the 'current user' has called the function (*recv* in this case) and its return value shows that the operation has completed. An operation can also be cancelled with *cancel/2*.

Instead of *Timeout = nowait* it is equivalent to create a *SelectHandle*) with *make\_ref()* and give as *Timeout*. This will then be the *SelectHandle* in the 'select' message, which enables a compiler optimization for receiving a message containing a newly created *reference()* (ignore the part of the message queue that had arrived before the the *reference()* was created).

Another message the user must be prepared for (when making asynchronous calls) is the *abort* message:

- **:**

  *{'$socket', socket(), abort, Info}*

This message indicates that the (asynchronous) operation has been aborted. If, for instance, the socket has been closed (by another process), *Info* will be *{SelectHandle, closed}*.

**Note:**

There is currently *no* support for Windows.

Support for IPv6 has been implemented but *not* tested.

SCTP has only been partly implemented (and not tested).

## DATA TYPES

```
invalid() = {invalid, What :: term()}
```

```
domain() = inet | inet6 | local | unspec
```

A lowercase *atom()* representing a protocol *domain* on the platform named *AF\_\** (or *PF\_\**).

The calls *supports()*, *is\_supported(ipv6)* and *is\_supported(local)* tells if the IPv6 protocol for the *inet6* protocol domain / address family, and if the *local* protocol domain / address family is supported by the platform's header files.

```
type() = stream | dgram | raw | rdm | seqpacket
```

A lowercase *atom()* representing a protocol *type* on the platform named *SOCK\_\**.

```
protocol() = atom()
```

An *atom()* means any *protocol* as enumerated by the *C* library call *getprotoent()* on the platform, or at least the supported ones of *ip \| ipv6 \| tcp \| udp \| sctp*.

See *open/2,3,4*

The call *supports(protocols)* returns which protocols are supported, and *is\_supported(protocols, Protocol)* tells if *Protocol* is among the enumerated.

```
socket() = {'$socket', socket_handle()}
```

As returned by *open/1,2,3,4* and *accept/1,2*.

```
socket_handle()
```

An opaque socket handle unique for the socket.

```
select_tag()
```

A tag that describes the (select) operation, contained in the returned *select\_info()*.

```
select_handle() = reference()
```

A *reference()* that uniquely identifies the (select) operation, contained in the returned *select\_info()*.

```
select_info() =
    {select_info,
     SelectTag :: select_tag(),
     SelectHandle :: select_handle()}
```

Returned by an operation that requires the caller to wait for a select message containing the *SelectHandle*.

```
info() =
    #{counters := #{atom() := integer() >= 0},
      iov_max := integer() >= 0,
      use_registry := boolean()}
```

The smallest allowed *iov\_max* value according to POSIX is *16*, but check your platform documentation to be sure.

```
socket_counters() =
    #{read_byte := integer() >= 0,
      read_fails := integer() >= 0,
      read_pkg := integer() >= 0,
      read_pkg_max := integer() >= 0,
      read_tries := integer() >= 0,
      read_waits := integer() >= 0,
      write_byte := integer() >= 0,
      write_fails := integer() >= 0,
      write_pkg := integer() >= 0,
      write_pkg_max := integer() >= 0,
      write_tries := integer() >= 0,
      write_waits := integer() >= 0,
      sendfile => integer() >= 0,
      sendfile_byte => integer() >= 0,
      sendfile_fails => integer() >= 0,
      sendfile_max => integer() >= 0,
      sendfile_pkg => integer() >= 0,
      sendfile_pkg_max => integer() >= 0,
      sendfile_tries => integer() >= 0,
      sendfile_waits => integer() >= 0,
      acc_success := integer() >= 0,
      acc_fails := integer() >= 0,
      acc_tries := integer() >= 0,
      acc_waits := integer() >= 0}
```

```
info_keys() =
    [domain | type | protocol | fd | owner | local_address |
     remote_address | recv | sent | state]
```

Defines the information elements of the table(s) printed by the i/0, i/1 and i/2 functions.

```
socket_info() =
    #{domain := domain() | integer(),
      type := type() | integer(),
      protocol := protocol() | integer(),
      owner := pid(),
      ctype := normal | fromfd | {fromfd, integer()},
      counters := socket_counters(),
      num_readers := integer() >= 0,
      num_writers := integer() >= 0,
      num_acceptors := integer() >= 0,
      writable := boolean(),
      readable := boolean(),
      rstates := [atom()],
      wstates := [atom()]}
```

```
in_addr() = {0..255, 0..255, 0..255, 0..255}
```

```
in6_addr() =
    {0..65535,
     0..65535,
     0..65535,
     0..65535,
     0..65535,
     0..65535,
     0..65535,
     0..65535}
```

```
sockaddr() =
    sockaddr_in() |
    sockaddr_in6() |
    sockaddr_un() |
    sockaddr_ll() |
    sockaddr_dl() |
    sockaddr_unspec() |
    sockaddr_native()
```

```
sockaddr_recv() = sockaddr() | binary()
```

```
sockaddr_in() =
    #{family := inet,
      port := port_number(),
      addr := any | broadcast | loopback | in_addr()}
```

```
sockaddr_in6() =
    #{family := inet6,
      port := port_number(),
      addr := any | loopback | in6_addr(),
      flowinfo := in6_flow_info(),
      scope_id := in6_scope_id()}
```

```
sockaddr_un() = #{family := local, path := binary() | string()}
```

The *path* element will always be a *binary* when returned from this module. When supplied to an API function in this module it may be a *string()*, which will be encoded into a binary according to the  native file name encoding  on the platform.

A terminating zero character will be appended before the address path is given to the OS, and the terminating zero will be stripped before giving the address path to the caller.

Linux's non-portable abstract socket address extension is handled by not doing any terminating zero processing in either direction, if the first byte of the address is zero.

```
sockaddr_ll() =
    #{family := packet,
      protocol := integer() >= 0,
      ifindex := integer(),
      pkttype := packet_type(),
      hatype := hatype(),
      addr := binary()}
```

```
sockaddr_dl() =
    #{family := link,
      index := integer() >= 0,
      type := integer() >= 0,
      nlen := integer() >= 0,
      alen := integer() >= 0,
      slen := integer() >= 0,
      data := binary()}
```

```
sockaddr_unspec() = #{family := unspec, addr := binary()}
```

```
sockaddr_native() = #{family := integer(), addr := binary()}
```

```
packet_type() =
    host | broadcast | multicast | otherhost | outgoing |
    loopback | user | kernel | fastroute |
    integer() >= 0
```

```
hatype() =
    netrom | eether | ether | ax25 | pronet | chaos | ieee802 |
    arcnet | appletlk | dlci | atm | metricom | ieee1394 | eui64 |
    infiniband | tunnel | tunnel6 | loopback | localtlk | none |
    void |
    integer() >= 0
```

```
port_number() = 0..65535
```

```
in6_flow_info() = 0..1048575
```

```
in6_scope_id() = 0..4294967295
```

```
msg_flag() =
    cmsg_cloexec | confirm | ctrunc | dontroute | eor | errqueue |
    more | oob | peek | trunc
```

Flags corresponding to the message flag constants on the platform. The flags are lowercase and the constants are uppercase with the prefix *MSG\_*.

Some flags are only used for sending, some only for receiving, some in received control messages, and some for several of these. Not all flags are supported on all platforms. See the platform's documentation, *supports(msg\_flags)*, and *is\_supported(msg\_flags, MsgFlag)*.

```
level() = socket | protocol()
```

The OS protocol levels for, for example, socket options and control messages, with the following names in the OS header files:

- ***socket*:**

  *SOL\_SOCKET* with options named *SO\_*\*.

- ***ip*:**

  *IPPROTO\_IP* a.k.a *SOL\_IP* with options named *IP\_*\*.

- ***ipv6*:**

  *IPPROTO\_IPV6* a.k.a *SOL\_IPV6* with options named *IPV6\_*\*.

- ***tcp*:**

  *IPPROTO\_TCP* with options named *TCP\_*\*.

- ***udp*:**

  *IPPROTO\_UDP* with options named *UDP\_*\*.

- ***sctp*:**

  *IPPROTO\_SCTP* with options named *SCTP\_*\*.

There are many other possible protocols, but the ones above are those for which this socket library implements socket options and/or control messages.

All protocols known to the OS are enumerated when the Erlang VM is started. See the OS man page for [protocols(5)](/protocols/5.md). The protocol level 'socket' is always implemented as *SOL\_SOCKET* and all the others mentioned in the list above are valid, if supported by the platform, enumerated or not.

The calls *supports()* and *is\_supported(protocols, Protocol)* can be used to find out if protocols *ipv6* and/or *sctp* are supported according to the platform's header files.

```
otp_socket_option() =
    debug | iow | controlling_process | rcvbuf | rcvctrlbuf |
    sndctrlbuf | meta | use_registry | fd | domain
```

These are socket options for the *otp* protocol level, that is *{otp, Name}* options, above all OS protocol levels. They affect Erlang/OTP's socket implementation.

- ***debug*:**

  *boolean()* - Activate debug printout.

- ***iow*:**

  *boolean()* - Inform On Wrap of statistics counters.

- ***controlling\_process*:**

  *pid()* - The socket "owner". Only the current controlling process can set this option.

- ***rcvbuf*:**

   *BufSize :: (default \| integer()\>0) \| {N :: integer()\>0, BufSize :: (default \| integer()\>0)}*  - Receive buffer size. The value *default* is only valid to *set*. *N* specifies the number of read attempts to do in a tight loop before assuming no more data is pending.

- ***rcvctrlbuf*:**

   *BufSize :: (default \| integer()\>0)*  - Buffer size for received ancillary messages. The value *default* is only valid to *set*.

- ***sndctrlbuf*:**

   *BufSize :: (default \| integer()\>0)*  - Buffer size for sent ancillary messages. The value *default* is only valid to *set*.

- ***fd*:**

  *integer()* - Only valid to *get*. The OS protocol levels' socket descriptor. Functions *open/1,2* can be used to create a socket according to this module from an existing OS socket descriptor.

- ***use\_registry*:**

  *boolean()* - Only valid to *get*. The value is set when the socket is created with *open/2* or *open/4*.

Options not described here are intentionally undocumented and for Erlang/OTP internal use only.

```
socket_option() =
    {Level :: socket,
     Opt ::
         acceptconn | acceptfilter | bindtodevice | broadcast |
         busy_poll | debug | domain | dontroute | error |
         keepalive | linger | mark | oobinline | passcred |
         peek_off | peercred | priority | protocol | rcvbuf |
         rcvbufforce | rcvlowat | rcvtimeo | reuseaddr |
         reuseport | rxq_ovfl | setfib | sndbuf | sndbufforce |
         sndlowat | sndtimeo | timestamp | type} |
    {Level :: ip,
     Opt ::
         add_membership | add_source_membership | block_source |
         dontfrag | drop_membership | drop_source_membership |
         freebind | hdrincl | minttl | msfilter | mtu |
         mtu_discover | multicast_all | multicast_if |
         multicast_loop | multicast_ttl | nodefrag | options |
         pktinfo | recvdstaddr | recverr | recvif | recvopts |
         recvorigdstaddr | recvtos | recvttl | retopts |
         router_alert | sndsrcaddr | tos | transparent | ttl |
         unblock_source} |
    {Level :: ipv6,
     Opt ::
         addrform | add_membership | authhdr | auth_level |
         checksum | drop_membership | dstopts | esp_trans_level |
         esp_network_level | faith | flowinfo | hopopts |
         ipcomp_level | join_group | leave_group | mtu |
         mtu_discover | multicast_hops | multicast_if |
         multicast_loop | portrange | pktoptions | recverr |
         recvhoplimit | hoplimit | recvpktinfo | pktinfo |
         recvtclass | router_alert | rthdr | tclass |
         unicast_hops | use_min_mtu | v6only} |
    {Level :: tcp,
     Opt ::
         congestion | cork | info | keepcnt | keepidle |
         keepintvl | maxseg | md5sig | nodelay | noopt | nopush |
         syncnt | user_timeout} |
    {Level :: udp, Opt :: cork} |
    {Level :: sctp,
     Opt ::
         adaption_layer | associnfo | auth_active_key |
         auth_asconf | auth_chunk | auth_key | auth_delete_key |
         autoclose | context | default_send_params |
         delayed_ack_time | disable_fragments | hmac_ident |
         events | explicit_eor | fragment_interleave |
         get_peer_addr_info | initmsg | i_want_mapped_v4_addr |
         local_auth_chunks | maxseg | maxburst | nodelay |
         partial_delivery_point | peer_addr_params |
         peer_auth_chunks | primary_addr | reset_streams |
         rtoinfo | set_peer_primary_addr | status |
         use_ext_recvinfo}
```

Socket option on the form *{Level, Opt}* where the OS protocol *Level* = *level()* and *Opt* is a socket option on that protocol level.

The OS name for an options is, except where otherwise noted, the *Opt* atom, in capitals, with prefix according to *level()*.

**Note:**

The *IPv6* option *pktoptions* is a special (barf) case. It is intended for backward compatibility usage only.

Do *not* use this option.

**Note:**

See the OS documentation for every socket option.

An option below that has the value type *boolean()* will translate the value *false* to a C *int* with value *0*, and the value *true* to *!!0* (not (not false)).

An option with value type *integer()* will be translated to a C *int* that may have a restricted range, for example byte: *0..255*. See the OS documentation.

The calls *supports(options)*, *supports(options, Level)* and *is\_supported(options, {Level, Opt})* can be used to find out which socket options that are supported by the platform.

*Options for protocol level* *socket*:

- ***{socket, acceptconn}*:**

  *Value = boolean()*

- ***{socket, bindtodevice}*:**

  *Value = string()*

- ***{socket, broadcast}*:**

  *Value = boolean()*

- ***{socket, debug}*:**

  *Value = integer()*

- ***{socket, domain}*:**

  *Value =* *domain()*

  Only valid to *get*.

  The socket's protocol domain. Does *not* work on for instance FreeBSD.

- ***{socket, dontroute}*:**

  *Value = boolean()*

- ***{socket, keepalive}*:**

  *Value = boolean()*

- ***{socket, linger}*:**

  *Value = abort \|* *linger()*

  The value *abort* is shorthand for *#{onoff =\> true, linger =\> 0}*, and only valid to *set*.

- ***{socket, oobinline}*:**

  *Value = boolean()*

- ***{socket, passcred}*:**

  *Value = boolean()*

- ***{socket, peek\_off}*:**

  *Value = integer()*

  Currently disabled due to a possible infinite loop when calling *recv/1-4* with *peek* in *Flags*.

- ***{socket, priority}*:**

  *Value = integer()*

- ***{socket, protocol}*:**

  *Value =* *protocol()*

  Only valid to *get*.

  The socket's protocol. Does *not* work on for instance Darwin.

- ***{socket, rcvbuf}*:**

  *Value = integer()*

- ***{socket, rcvlowat}*:**

  *Value = integer()*

- ***{socket, rcvtimeo}*:**

  *Value =* *timeval()*

  This option is unsupported per default; OTP has to be explicitly built with the *--enable-esock-rcvsndtimeo* configure option for this to be available.

  Since our implementation uses nonblocking sockets, it is unknown if and how this option works, or even if it may cause malfunction. Therefore, we do not recommend setting this option.

  Instead, use the *Timeout* argument to, for instance, the *recv/3* function.

- ***{socket, reuseaddr}*:**

  *Value = boolean()*

- ***{socket, reuseport}*:**

  *Value = boolean()*

- ***{socket, sndbuf}*:**

  *Value = integer()*

- ***{socket, sndlowat}*:**

  *Value = integer()*

- ***{socket, sndtimeo}*:**

  *Value =* *timeval()*

  This option is unsupported per default; OTP has to be explicitly built with the *--enable-esock-rcvsndtimeo* configure option for this to be available.

  Since our implementation uses nonblocking sockets, it is unknown if and how this option works, or even if it may cause malfunction. Therefore, we do not recommend setting this option.

  Instead, use the *Timeout* argument to, for instance, the *send/3* function.

- ***{socket, timestamp}*:**

  *Value = boolean()*

- ***{socket, type}*:**

  *Value =* *type()*

  Only valid to *get*.

  The socket's type.

*Options for protocol level* *ip*:

- ***{ip, add\_membership}*:**

  *Value =* *ip\_mreq()*

  Only valid to *set*.

- ***{ip, add\_source\_membership}*:**

  *Value =* *ip\_mreq\_source()*

  Only valid to *set*.

- ***{ip, block\_source}*:**

  *Value =* *ip\_mreq\_source()*

  Only valid to *set*.

- ***{ip, drop\_membership}*:**

  *Value =* *ip\_mreq()*

  Only valid to *set*.

- ***{ip, drop\_source\_membership}*:**

  *Value =* *ip\_mreq\_source()*

  Only valid to *set*.

- ***{ip, freebind}*:**

  *Value = boolean()*

- ***{ip, hdrincl}*:**

  *Value = boolean()*

- ***{ip, minttl}*:**

  *Value = integer()*

- ***{ip, msfilter}*:**

  *Value =* *null \|* *ip\_msfilter()*

  Only valid to *set*.

  The value *null* passes a *NULL* pointer and size *0* to the C library call.

- ***{ip, mtu}*:**

  *Value = integer()*

  Only valid to *get*.

- ***{ip, mtu\_discover}*:**

  *Value =* *ip\_pmtudisc()* *\| integer()*

  An *integer()* value is according to the platform's header files.

- ***{ip, multicast\_all}*:**

  *Value = boolean()*

- ***{ip, multicast\_if}*:**

  *Value =* *any \|* *in\_addr()*

- ***{ip, multicast\_loop}*:**

  *Value = boolean()*

- ***{ip, multicast\_ttl}*:**

  *Value = integer()*

- ***{ip, nodefrag}*:**

  *Value = boolean()*

- ***{ip, pktinfo}*:**

  *Value = boolean()*

- ***{ip, recvdstaddr}*:**

  *Value = boolean()*

- ***{ip, recverr}*:**

  *Value = boolean()*

  *Warning!* When this option is enabled, error messages may arrive on the socket's error queue, which should be read using the message flag *errqueue*, and using *recvmsg/1,2,3,4,5* to get all error information in the message's *ctrl* field as a control message *#{level := ip, type := recverr}*.

  A working strategy should be to first poll the error queue using *recvmsg/2,3,4* with *Timeout =:= 0* and *Flags* containing *errqueue* (ignore the return value *{error, timeout}*) before reading the actual data to ensure that the error queue gets cleared. And read the data using one of the *nowait \|* *select\_handle()* recv functions: *recv/3,4*, *recvfrom/3,4* or *recvmsg/3,4,5*. Otherwise you might accidentally cause a busy loop in and out of 'select' for the socket.

- ***{ip, recvif}*:**

  *Value = boolean()*

- ***{ip, recvopts}*:**

  *Value = boolean()*

- ***{ip, recvorigdstaddr}*:**

  *Value = boolean()*

- ***{ip, recvtos}*:**

  *Value = boolean()*

- ***{ip, recvttl}*:**

  *Value = boolean()*

- ***{ip, retopts}*:**

  *Value = boolean()*

- ***{ip, router\_alert}*:**

  *Value = integer()*

- ***{ip, sendsrcaddr}*:**

  *Value = boolean()*

- ***{ip, tos}*:**

  *Value =* *ip\_tos()*  *\| integer()*

  An *integer()* value is according to the platform's header files.

- ***{ip, transparent}*:**

  *Value = boolean()*

- ***{ip, ttl}*:**

  *Value = integer()*

- ***{ip, unblock\_source}*:**

  *Value =* *ip\_mreq\_source()*

  Only valid to *set*.

*Options for protocol level* *ipv6*:

- ***{ipv6, addrform}*:**

  *Value =* *domain()*

  As far as we know the only valid value is *inet* and it is only allowed for an IPv6 socket that is connected and bound to an IPv4-mapped IPv6 address.

- ***{ipv6, add\_membership}*:**

  *Value =* *ipv6\_mreq()*

  Only valid to *set*.

- ***{ipv6, authhdr}*:**

  *Value = boolean()*

- ***{ipv6, drop\_membership}*:**

  *Value =* *ipv6\_mreq()*

  Only valid to *set*.

- ***{ipv6, dstopts}*:**

  *Value = boolean()*

- ***{ipv6, flowinfo}*:**

  *Value = boolean()*

- ***{ipv6, hoplimit}*:**

  *Value = boolean()*

- ***{ipv6, hopopts}*:**

  *Value = boolean()*

- ***{ipv6, mtu}*:**

  *Value = integer()*

- ***{ipv6, mtu\_discover}*:**

  *Value =* *ipv6\_pmtudisc()* *\| integer()*

  An *integer()* value is according to the platform's header files.

- ***{ipv6, multicast\_hops}*:**

  *Value =* *ipv6\_hops()*

- ***{ipv6, multicast\_if}*:**

  *Value = integer()*

- ***{ipv6, multicast\_loop}*:**

  *Value = boolean()*

- ***{ipv6, recverr}*:**

  *Value = boolean()*

  *Warning!* See the socket option *{ip, recverr}* regarding the socket's error queue. The same warning applies for this option.

- ***{ipv6, recvhoplimit}*:**

  *Value = boolean()*

- ***{ipv6, recvpktinfo}*:**

  *Value = boolean()*

- ***{ipv6, recvtclass}*:**

  *Value = boolean()*

- ***{ipv6, router\_alert}*:**

  *Value = integer()*

- ***{ipv6, rthdr}*:**

  *Value = boolean()*

- ***{ipv6, tclass}*:**

  *Value = boolean()*

- ***{ipv6, unicast\_hops}*:**

  *Value =* *ipv6\_hops()*

- ***{ipv6, v6only}*:**

  *Value = boolean()*

*Options for protocol level* *sctp*. See also RFC 6458.

- ***{sctp, associnfo}*:**

  *Value =* *sctp\_assocparams()*

- ***{sctp, autoclose}*:**

  *Value = integer()*

- ***{sctp, disable\_fragments}*:**

  *Value = boolean()*

- ***{sctp, events}*:**

  *Value =* *sctp\_event\_subscribe()*

  Only valid to *set*.

- ***{sctp, initmsg}*:**

  *Value =* *sctp\_initmsg()*

- ***{sctp, maxseg}*:**

  *Value = integer()*

- ***{sctp, nodelay}*:**

  *Value = boolean()*

- ***{sctp, rtoinfo}*:**

  *Value =* *sctp\_rtoinfo()*

*Options for protocol level* *tcp*:

- ***{tcp, congestion}*:**

  *Value = string()*

- ***{tcp, cork}*:**

  *Value = boolean()*

- ***{tcp, maxseg}*:**

  *Value = integer()*

- ***{tcp, nodelay}*:**

  *Value = boolean()*

*Options for protocol level* *udp*:

- ***{udp, cork}*:**

  *Value = boolean()*

```
linger() = #{onoff := boolean(), linger := integer() >= 0}
```

Corresponds to the C *struct linger* for managing the socket option *{socket, linger}*.

```
timeval() = #{sec := integer(), usec := integer()}
```

Corresponds to the C *struct timeval*. The field *sec* holds seconds, and *usec* microseconds.

```
ip_mreq() = #{multiaddr := in_addr(), interface := in_addr()}
```

Corresponds to the C *struct ip\_mreq* for managing multicast groups.

```
ip_mreq_source() =
    #{multiaddr := in_addr(),
      interface := in_addr(),
      sourceaddr := in_addr()}
```

Corresponds to the C *struct ip\_mreq\_source* for managing multicast groups.

```
ip_msfilter() =
    #{multiaddr := in_addr(),
      interface := in_addr(),
      mode := include | exclude,
      slist := [in_addr()]}
```

Corresponds to the C *struct ip\_msfilter* for managing multicast source filtering (RFC 3376).

```
ip_pmtudisc() = want | dont | do | probe
```

Lowercase *atom()* values corresponding to the C library constants *IP\_PMTUDISC\_\**. Some constant(s) may be unsupported by the platform.

```
ip_tos() = lowdelay | throughput | reliability | mincost
```

Lowercase *atom()* values corresponding to the C library constants *IPTOS\_\**. Some constant(s) may be unsupported by the platform.

```
ip_pktinfo() =
    #{ifindex := integer() >= 0,
      spec_dst := in_addr(),
      addr := in_addr()}
```

```
ipv6_mreq() =
    #{multiaddr := in6_addr(), interface := integer() >= 0}
```

Corresponds to the C *struct ipv6\_mreq* for managing multicast groups. See also RFC 2553.

```
ipv6_hops() = default | 0..255
```

The value *default* is only valid to *set* and is translated to the C value *-1*, meaning the route default.

```
ipv6_pmtudisc() = want | dont | do | probe
```

Lowercase *atom()* values corresponding to the C library constants *IPV6\_PMTUDISC\_\**. Some constant(s) may be unsupported by the platform.

```
ipv6_pktinfo() = #{addr := in6_addr(), ifindex := integer()}
```

```
sctp_assocparams() =
    #{assoc_id := integer(),
      asocmaxrxt := 0..65535,
      numbe_peer_destinations := 0..65535,
      peer_rwnd := 0..4294967295,
      local_rwnd := 0..4294967295,
      cookie_life := 0..4294967295}
```

Corresponds to the C *struct sctp\_assocparams*.

```
sctp_event_subscribe() =
    #{data_io := boolean(),
      association := boolean(),
      address := boolean(),
      send_failure := boolean(),
      peer_error := boolean(),
      shutdown := boolean(),
      partial_delivery := boolean(),
      adaptation_layer => boolean(),
      sender_dry => boolean()}
```

Corresponds to the C *struct sctp\_event\_subscribe*.

Not all fields are implemented on all platforms; unimplemented fields are ignored, but implemented fields are mandatory. Note that the '\_event' suffixes have been stripped from the C struct field names, for convenience.

```
sctp_initmsg() =
    #{num_ostreams := 0..65535,
      max_instreams := 0..65535,
      max_attempts := 0..65535,
      max_init_timeo := 0..65535}
```

Corresponds to the C *struct sctp\_initmsg*.

```
sctp_rtoinfo() =
    #{assoc_id := integer(),
      initial := 0..4294967295,
      max := 0..4294967295,
      min := 0..4294967295}
```

Corresponds to the C *struct sctp\_rtoinfo*.

```
msg() = msg_send() | msg_recv()
```

```
msg_send() =
    #{addr => sockaddr(),
      iov := erlang:iovec(),
      ctrl =>
          [cmsg_send() |
           #{level := level() | integer(),
             type := integer(),
             data := binary()}]}
```

Message sent by *sendmsg/2,3,4*.

Corresponds to a C *struct msghdr*, see your platform documentation for *[sendmsg(2)](/sendmsg/2.md)*.

- ***addr*:**

   Optional peer address, used on unconnected sockets. Corresponds to *msg\_name* and *msg\_namelen* fields of a *struct msghdr*. If not used they are set to *NULL*, *0*.

- ***iov*:**

   Mandatory data as a list of binaries. The *msg\_iov* and *msg\_iovlen* fields of a *struct msghdr*.

- ***ctrl*:**

   Optional list of control messages (CMSG). Corresponds to the *msg\_control* and *msg\_controllen* fields of a *struct msghdr*. If not used they are set to *NULL*, *0*.

The *msg\_flags* field of the *struct msghdr* is set to *0*.

```
msg_recv() =
    #{addr => sockaddr_recv(),
      iov := erlang:iovec(),
      ctrl :=
          [cmsg_recv() |
           #{level := level() | integer(),
             type := integer(),
             data := binary()}],
      flags := [msg_flag() | integer()]}
```

Message returned by *recvmsg/1,2,3,5*.

Corresponds to a C *struct msghdr*, see your platform documentation for *[recvmsg(2)](/recvmsg/2.md)*.

- ***addr*:**

   Optional peer address, used on unconnected sockets. Corresponds to *msg\_name* and *msg\_namelen* fields of a *struct msghdr*. If *NULL* the map key is not present.

- ***iov*:**

   Data as a list of binaries. The *msg\_iov* and *msg\_iovlen* fields of a *struct msghdr*.

- ***ctrl*:**

   A possibly empty list of control messages (CMSG). Corresponds to the *msg\_control* and *msg\_controllen* fields of a *struct msghdr*.

- ***flags*:**

   Message flags. Corresponds to the *msg\_flags* field of a *struct msghdr*. Unknown flags, if any, are returned in one *integer()*, last in the containing list.

```
native_value() = integer() | boolean() | binary()
```

```
cmsg_send() =
    #{level := socket,
      type := timestamp,
      data => native_value(),
      value => timeval()} |
    #{level := socket, type := rights, data := native_value()} |
    #{level := socket,
      type := credentials,
      data := native_value()} |
    #{level := ip,
      type := tos,
      data => native_value(),
      value => ip_tos() | integer()} |
    #{level := ip,
      type := ttl,
      data => native_value(),
      value => integer()} |
    #{level := ip,
      type := hoplimit,
      data => native_value(),
      value => integer()} |
    #{level := ipv6,
      type := tclass,
      data => native_value(),
      value => integer()}
```

Control messages (ancillary messages) accepted by *sendmsg/2,3,4*.

A control message may for some message types have a *value* field with a symbolic value, or a *data* field with a native value, that has to be binary compatible what is defined in the platform's header files.

```
cmsg_recv() =
    #{level := socket,
      type := timestamp,
      data := binary(),
      value => timeval()} |
    #{level := socket, type := rights, data := binary()} |
    #{level := socket, type := credentials, data := binary()} |
    #{level := ip,
      type := tos,
      data := binary(),
      value => ip_tos() | integer()} |
    #{level := ip,
      type := recvtos,
      data := binary(),
      value := ip_tos() | integer()} |
    #{level := ip,
      type := ttl,
      data := binary(),
      value => integer()} |
    #{level := ip,
      type := recvttl,
      data := binary(),
      value := integer()} |
    #{level := ip,
      type := pktinfo,
      data := binary(),
      value => ip_pktinfo()} |
    #{level := ip,
      type := origdstaddr,
      data := binary(),
      value => sockaddr_recv()} |
    #{level := ip,
      type := recverr,
      data := binary(),
      value => extended_err()} |
    #{level := ipv6,
      type := hoplimit,
      data := binary(),
      value => integer()} |
    #{level := ipv6,
      type := pktinfo,
      data := binary(),
      value => ipv6_pktinfo()} |
    #{level := ipv6,
      type := recverr,
      data := binary(),
      value => extended_err()} |
    #{level := ipv6,
      type := tclass,
      data := binary(),
      value => integer()}
```

Control messages (ancillary messages) returned by *recvmsg/1,2,3,5*.

A control message has got a *data* field with a native (*binary*) value for the message data, and may also have a decoded *value* field if this socket library successfully decoded the data.

```
icmp_dest_unreach() =
    net_unreach | host_unreach | port_unreach | frag_needed |
    net_unknown | host_unknown
```

```
icmpv6_dest_unreach() =
    noroute | adm_prohibited | not_neighbour | addr_unreach |
    port_unreach | policy_fail | reject_route
```

```
ee_origin() = none | local | icmp | icmp6
```

```
extended_err() =
    #{error := posix(),
      origin := icmp,
      type := dest_unreach,
      code := icmp_dest_unreach() | 0..255,
      info := 0..4294967295,
      data := 0..4294967295,
      offender := sockaddr_recv()} |
    #{error := posix(),
      origin := icmp,
      type := time_exceeded | 0..255,
      code := 0..255,
      info := 0..4294967295,
      data := 0..4294967295,
      offender := sockaddr_recv()} |
    #{error := posix(),
      origin := icmp6,
      type := dest_unreach,
      code := icmpv6_dest_unreach() | 0..255,
      info := 0..4294967295,
      data := 0..4294967295,
      offender := sockaddr_recv()} |
    #{error := posix(),
      origin := icmp6,
      type := pkt_toobig | time_exceeded | 0..255,
      code := 0..255,
      info := 0..4294967295,
      data := 0..4294967295,
      offender := sockaddr_recv()} |
    #{error := posix(),
      origin := ee_origin() | 0..255,
      type := 0..255,
      code := 0..255,
      info := 0..4294967295,
      data := 0..4294967295,
      offender := sockaddr_recv()}
```

```
posix() = inet:posix()
```

The POSIX error codes originates from the OS level socket interface.

## EXPORTS

```
accept(ListenSocket) -> {ok, Socket} | {error, Reason}
```

```
accept(ListenSocket, Timeout :: infinity) ->
          {ok, Socket} | {error, Reason}
```

Types:

ListenSocket = Socket = socket()\
 Reason = posix() \| closed \| invalid()\

Accept a connection on a socket.

This call is used with connection oriented socket types (*stream* or *seqpacket*). It returns the first pending incoming connection for a listen socket, or waits for one to arrive, and returns the (newly) connected socket.

```
accept(ListenSocket, Timeout :: integer() >= 0) ->
          {ok, Socket} | {error, Reason}
```

Types:

ListenSocket = Socket = socket()\
 Reason = posix() \| closed \| invalid() \| timeout\

The same as accept/1 but returns *{error, timeout}* if no connection has been accepted after *Timeout* milliseconds.

```
accept(ListenSocket, Timeout :: nowait) ->
          {ok, Socket} | {select, SelectInfo} | {error, Reason}
```

```
accept(ListenSocket, SelectHandle :: select_handle()) ->
          {ok, Socket} | {select, SelectInfo} | {error, Reason}
```

Types:

ListenSocket = Socket = socket()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

The same as accept/1 but returns promptly.

When there is no pending connection to return, the function will return *{select, SelectInfo}*, and the caller will later receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* contained in the *SelectInfo* ) when a client connects. A subsequent call to *accept/1,2* will then return the socket.

If the time-out argument is *SelectHandle*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If the time-out argument is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

If the caller doesn't want to wait for a connection, it must immediately call *cancel/2* to cancel the operation.

```
bind(Socket, Addr) -> ok | {error, Reason}
```

Types:

Socket = socket()\
 Addr = sockaddr() \| any \| broadcast \| loopback\
 Reason = posix() \| closed \| invalid()\

Bind a name to a socket.

When a socket is created (with *open*), it has no address assigned to it. *bind* assigns the address specified by the *Addr* argument.

The rules used for name binding vary between domains.

If you bind a socket to an address in for example the 'inet' or 'inet6' address families, with an ephemeral port number (0), and want to know which port that was chosen, you can find out using something like: *{ok, #{port := Port}} =* *socket:sockname(Socket)*

```
cancel(Socket, SelectInfo) -> ok | {error, Reason}
```

Types:

Socket = socket()\
 SelectInfo = select\_info()\
 Reason = closed \| invalid()\

Cancel an asynchronous request.

Call this function in order to cancel a previous asynchronous call to, e.g. *recv/3*.

An ongoing asynchronous operation blocks the socket until the operation has been finished in good order, or until it has been cancelled by this function.

Any other process that tries an operation of the same basic type (accept / send / recv) will be enqueued and notified with the regular *select* mechanism for asynchronous operations when the current operation and all enqueued before it has been completed.

If *SelectInfo* does not match an operation in progress for the calling process, this function returns *{error, {invalid, SelectInfo}}*.

```
close(Socket) -> ok | {error, Reason}
```

Types:

Socket = socket()\
 Reason = posix() \| closed \| timeout\

Closes the socket.

**Note:**

Note that for e.g. *protocol* = *tcp*, most implementations 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 (*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.

```
connect(Socket, SockAddr) -> ok | {error, Reason}
```

```
connect(Socket, SockAddr, Timeout :: infinity) ->
           ok | {error, Reason}
```

Types:

Socket = socket()\
 SockAddr = sockaddr()\
 Reason = posix() \| closed \| invalid() \| already\

This function connects the socket to the address specified by the *SockAddr* argument, and returns when the connection has been established or failed.

If a connection attempt is already in progress (by another process), *{error, already}* is returned.

```
connect(Socket, SockAddr, Timeout :: integer() >= 0) ->
           ok | {error, Reason}
```

Types:

Socket = socket()\
 SockAddr = sockaddr()\
 Reason = posix() \| closed \| invalid() \| already \| timeout\

The same as connect/2 but returns *{error, timeout}* if no connection has been established after *Timeout* milliseconds.

**Note:**

Note that when this call has returned *{error, timeout}* the connection state of the socket is uncertain since the platform's network stack may complete the connection at any time, up to some platform specific time-out.

Repeating a connection attempt towards the same address would be ok, but towards a different address could end up with a connection to either address.

The safe play would be to close the socket and start over.

Also note that all this applies to cancelling a connect call with a no-wait time-out described below.

```
connect(Socket, SockAddr, Timeout :: nowait) ->
           ok | {select, SelectInfo} | {error, Reason}
```

```
connect(Socket, SockAddr, SelectHandle :: select_handle()) ->
           ok | {select, SelectInfo} | {error, Reason}
```

Types:

Socket = socket()\
 SockAddr = sockaddr()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid() \| already\

The same as connect/2 but returns promptly.

If it is not possible to immediately establish a connection, the function will return *{select, SelectInfo}*, and the caller will later receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* contained in the *SelectInfo* ) when the connection has been completed or failed. A subsequent call to *connect/1* will then finalize the connection and return the result.

If the time-out argument is *SelectHandle*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If the time-out argument is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

If the caller doesn't want to wait for the connection to complete, it must immediately call *cancel/2* to cancel the operation.

```
connect(Socket) -> ok | {error, Reason}
```

Types:

Socket = socket()\
 Reason = posix() \| closed \| invalid()\

This function finalizes a connection setup on a socket, after calling *connect(\_, \_, nowait \| select\_handle())* that returned *{select, SelectInfo}*, and receiving the select message *{'$socket', Socket, select, SelectHandle}*, and returns whether the connection setup was successful or not.

Instead of calling this function, for backwards compatibility, it is allowed to call *connect/2,3*, but that incurs more overhead since the connect address and time-out are processed in vain.

```
cancel_monitor(MRef) -> boolean()
```

Types:

MRef = reference()\

If *MRef* is a reference that the calling process obtained by calling *monitor/1*, this monitor is turned off. If the monitoring is already turned off, nothing happens.

The returned value is one of the following:

- ***true*:**

  The monitor was found and removed. In this case, no *'DOWN'* message corresponding to this monitor has been delivered and will not be delivered.

- ***false*:**

  The monitor was not found and could not be removed. This probably because a *'DOWN'* message corresponding to this monitor has already been placed in the caller message queue.

Failure: It is an error if *MRef* refers to a monitor started by another process.

```
getopt(X1 :: socket(),
       SocketOption :: {Level :: otp, Opt :: otp_socket_option()}) ->
          {ok, Value :: term()} | {error, invalid() | closed}
```

Gets a socket option from the protocol level *otp*, which is this implementation's level above the OS protocol layers.

See the type  otp\_socket\_option()  for a description of the options on this level.

```
getopt(X1 :: socket(), SocketOption :: socket_option()) ->
          {ok, Value :: term()} |
          {error, posix() | invalid() | closed}
```

Gets a socket option from one of the OS's protocol levels. See the type socket\_option() for which options that this implementation knows about, how they are related to option names in the OS, and if there are known peculiarities with any of them.

What options are valid depends on what kind of socket it is (*domain()*, *type()* and *protocol()*).

See the  socket options  chapter of the users guide for more info.

**Note:**

Not all options are valid, nor possible to get, on all platforms. That is, even if "we" support an option; it does not mean that the underlying OS does.

**getopt(Socket, Level, Opt) -\> ok \| {error, Reason}**\

Types:

 Socket = socket()\
\
  Reason = inet:posix() \| *invalid()* \| closed \

Backwards compatibility function.

The same as *getopt(Socket, {Level, Opt})*

```
getopt_native(X1 :: socket(),
              SocketOption ::
                  socket_option() |
                  {Level :: level() | (NativeLevel :: integer()),
                   NativeOpt :: integer()},
              ValueType :: integer) ->
                 {ok, Value :: integer()} |
                 {error, posix() | invalid() | closed}
```

```
getopt_native(X1 :: socket(),
              SocketOption ::
                  socket_option() |
                  {Level :: level() | (NativeLevel :: integer()),
                   NativeOpt :: integer()},
              ValueType :: boolean) ->
                 {ok, Value :: boolean()} |
                 {error, posix() | invalid() | closed}
```

```
getopt_native(X1 :: socket(),
              SocketOption ::
                  socket_option() |
                  {Level :: level() | (NativeLevel :: integer()),
                   NativeOpt :: integer()},
              ValueSize :: integer() >= 0) ->
                 {ok, Value :: binary()} |
                 {error, posix() | invalid() | closed}
```

```
getopt_native(X1 :: socket(),
              SocketOption ::
                  socket_option() |
                  {Level :: level() | (NativeLevel :: integer()),
                   NativeOpt :: integer()},
              ValueSpec :: binary()) ->
                 {ok, Value :: binary()} |
                 {error, posix() | invalid() | closed}
```

Gets a socket option that may be unknown to our implementation, or that has a type not compatible with our implementation, that is; in "native mode".

The socket option may be specified with an ordinary *socket\_option()* tuple, with a known *Level = level()* and an integer *NativeOpt*, or with both an integer *NativeLevel* and *NativeOpt*.

How to decode the option value has to be specified either with *ValueType*, by specifying the *ValueSize* for a *binary()* that will contain the fetched option value, or by specifying a *binary()* *ValueSpec* that will be copied to a buffer for the *getsockopt()* call to write the value in which will be returned as a new *binary()*.

If *ValueType* is *integer* a *C* type *(int)* will be fetched, if it is *boolean* a *C* type *(int)* will be fetched and converted into a *boolean()* according to the *C* implementation.

What options are valid depends on what kind of socket it is (*domain()*, *type()* and *protocol()*).

The integer values for *NativeLevel* and *NativeOpt* as well as the *Value* encoding has to be deduced from the header files for the running system.

```
i() -> ok
```

Print all sockets in table format in the erlang shell.

```
i(InfoKeys) -> ok
```

Types:

InfoKeys = info\_keys()\

Print all sockets in table format in the erlang shell. What information is included is defined by *InfoKeys*.

```
i(Domain) -> ok
```

Types:

Domain = inet \| inet6 \| local\

Print a selection, based on domain, of the sockets in table format in the erlang shell.

```
i(Proto) -> ok
```

Types:

Proto = sctp \| tcp \| udp\

Print a selection, based on protocol, of the sockets in table format in the erlang shell.

```
i(Type) -> ok
```

Types:

Type = dgram \| seqpacket \| stream\

Print a selection, based on type, of the sockets in table format in the erlang shell.

```
i(Domain, InfoKeys) -> ok
```

Types:

Domain = inet \| inet6 \| local\
 InfoKeys = info\_keys()\

Print a selection, based on domain, of the sockets in table format in the erlang shell. What information is included is defined by *InfoKeys*.

```
i(Proto, InfoKeys) -> ok
```

Types:

Proto = sctp \| tcp \| udp\
 InfoKeys = info\_keys()\

Print a selection, based on domain, of the sockets in table format in the erlang shell. What information is included is defined by *InfoKeys*.

```
i(Type, InfoKeys) -> ok
```

Types:

Type = dgram \| seqpacket \| stream\
 InfoKeys = info\_keys()\

Print a selection, based on type, of the sockets in table format in the erlang shell. What information is included is defined by *InfoKeys*.

```
info() -> info()
```

Get miscellaneous info about the socket library.

The function returns a map with each info item as a key-value binding.

**Note:**

In order to ensure data integrity, mutex'es are taken when needed. So, do not call this function often.

```
info(Socket) -> socket_info()
```

Types:

Socket = socket()\

Get miscellaneous info about the socket.

The function returns a map with each info item as a key-value binding. It reflects the "current" state of the socket.

**Note:**

In order to ensure data integrity, mutex'es are taken when needed. So, do not call this function often.

```
ioctl(Socket, GetRequest) -> {ok, IFConf} | {error, Reason}
```

Types:

Socket = socket()\
 GetRequest = gifconf\
 IFConf = \[#{name := string, addr := sockaddr()}\]\
 Reason = posix() \| closed\

Retrieve socket (device) parameters.

```
ioctl(Socket, GetRequest, NameOrIndex) ->
         {ok, Result} | {error, Reason}
```

Types:

Socket = socket()\
 GetRequest = \
\
     gifname \| gifindex \| gifaddr \| gifdstaddr \| gifbrdaddr \|\
\
     gifnetmask \| gifhwaddr \| gifmtu \| giftxqlen \| gifflags\
 NameOrIndex = string() \| integer()\
 Result = term()\
 Reason = posix() \| closed\

Retrieve socket (device) parameters. This function retrieves a specific parameter, according to *GetRequest* argument. The third argument is the (lookup) "key", identifying the interface (usually the name of the interface).

- ***gifname*:**

  Get the name of the interface with the specified index (integer()).

  Result, name of the interface, is a *string()*.

- ***gifindex*:**

  Get the index of the interface with the specified name.

  Result, interface index, is a *integer()*.

- ***gifaddr*:**

  Get the address of the interface with the specified name. Result, address of the interface, is a *socket:sockaddr()*.

- ***gifdstaddr*:**

  Get the destination address of the point-to-point interface with the specified name.

  Result, destination address of the interface, is a *socket:sockaddr()*.

- ***gifbrdaddr*:**

  Get the droadcast address for the interface with the specified name.

  Result, broadcast address of the interface, is a *socket:sockaddr()*.

- ***gifnetmask*:**

  Get the network mask for the interface with the specified name.

  Result, network mask of the interface, is a *socket:sockaddr()*.

- ***gifhwaddr*:**

  Get the hardware address for the interface with the specified name.

  Result, hardware address of the interface, is a *socket:sockaddr()*. The family field contains the 'ARPHRD' device type (or an integer).

- ***gifmtu*:**

  Get the MTU (Maximum Transfer Unit) for the interface with the specified name.

  Result, MTU of the interface, is an *integer()*.

- ***giftxqlen*:**

  Get the transmit queue length of the interface with the specified name.

  Result, transmit queue length of the interface, is an *integer()*.

- ***gifflags*:**

  Get the active flag word of the interface with the specified name.

  Result, the active flag word of the interface, is an list of *socket:ioctl\_device\_flag() \| integer()*.

```
ioctl(Socket, SetRequest, Name, Value) -> ok | {error, Reason}
```

Types:

Socket = socket()\
 SetRequest = \
\
     sifflags \| sifaddr \| sifdstaddr \| sifbrdaddr \| sifnetmask \|\
\
     sifhwaddr \| gifmtu \| siftxqlen\
 Name = string()\
 Value = term()\
 Reason = posix() \| closed\

Set socket (device) parameters. This function sets a specific parameter, according to *SetRequest* argument. The third argument is the "key", identifying the interface (usually the name of the interface), and the fourth is the "new" value.

These are privileged operation's.

- ***sifflags*:**

  Set the the active flag word, *#{Flag =\> boolean()}*, of the interface with the specified name.

  Each flag to be changed, should be added to the value map, with the value *'true'* if the flag (*Flag*) should be set and *'false'* if the flag should be reset.

- ***sifaddr*:**

  Set the address, *sockaddr()*, of the interface with the specified name.

- ***sifdstaddr*:**

  Set the destination address, *sockaddr()*, of a point-to-point interface with the specified name.

- ***sifbrdaddr*:**

  Set the broadcast address, *sockaddr()*, of the interface with the specified name.

- ***sifnetmask*:**

  Set the network mask, *sockaddr()*, of the interface with the specified name.

- ***sifmtu*:**

  Set the MTU (Maximum Transfer Unit), *integer()*, for the interface with the specified name.

- ***siftxqlen*:**

  Set the transmit queue length, *integer()*, of the interface with the specified name.

```
is_supported(Key1 :: term()) -> boolean()
```

```
is_supported(Key1 :: term(), Key2 :: term()) -> boolean()
```

This function retrieves information about what the platform supports, such as if SCTP is supported, or if a socket options are supported.

For keys other than the known *false* is returned. Note that in a future version or on a different platform there might be more supported items.

This functions returns a *boolean* corresponding to what *supports/0-2* reports for the same *Key1* (and *Key2*).

```
listen(Socket) -> ok | {error, Reason}
```

```
listen(Socket, Backlog) -> ok | {error, Reason}
```

Types:

Socket = socket()\
 Backlog = integer()\
 Reason = posix() \| closed\

Listen for connections on a socket.

```
monitor(Socket) -> reference()
```

Types:

Socket = socket()\

Start monitor the socket *Socket*.

If the monitored socket does not exist or when the monitor is triggered, a *'DOWN'* message is sent that has the following pattern:

```
	    {'DOWN', MonitorRef, socket, Object, Info}
```

In the monitor message *MonitorRef* and *Type* are the same as described earlier, and:

- ***Object*:**

  The monitored entity, socket, which triggered the event.

- ***Info*:**

  Either the termination reason of the socket or *nosock* (socket *Socket* did not exist at the time of monitor creation).

Making several calls to *socket:monitor/1* for the same *Socket* is not an error; it results in as many independent monitoring instances.

```
number_of() -> integer() >= 0
```

Returns the number of active sockets.

```
open(FD) -> {ok, Socket} | {error, Reason}
```

```
open(FD, Opts) -> {ok, Socket} | {error, Reason}
```

Types:

FD = integer()\
 Opts = \
\
     \#{domain =\> domain() \| integer(),\
\
       type =\> type() \| integer(),\
\
       protocol =\> default \| protocol() \| integer(),\
\
       dup =\> boolean(),\
\
       debug =\> boolean(),\
\
       use\_registry =\> boolean()}\
 Socket = socket()\
 Reason = posix() \| domain \| type \| protocol\

Creates an endpoint (socket) for communication based on an already existing file descriptor. The function attempts to retrieve *domain*, *type* and *protocol* from the system. This is however not possible on all platforms, and they should then be specified in *Opts*.

The *Opts* argument is intended for providing extra information for the open call:

- ***domain*:**

  Which protocol domain is the descriptor of. See also *open/2,3,4*.

- ***type*:**

  Which protocol type type is the descriptor of.

  See also *open/2,3,4*.

- ***protocol*:**

  Which protocol is the descriptor of. The atom *default* is equivalent to the integer protocol number *0* which means the default protocol for a given domain and type.

  If the protocol can not be retrieved from the platform for the socket, and *protocol* is not specified, the default protocol is used, which may or may not be correct.

  See also *open/2,3,4*.

- ***dup*:**

  Shall the provided descriptor be duplicated (dup) or not. \
   Defaults to *true*.

- ***debug*:**

  Enable or disable debug during the open call. \
   Defaults to *false*.

- ***use\_registry\>*:**

  Enable or disable use of the socket registry for this socket. This overrides the global value. \
   Defaults to the global value, see *use\_registry/1*.

**Note:**

This function should be used with care!

On some platforms it is *necessary* to provide *domain*, *type* and *protocol* since they cannot be retrieved from the platform.

```
open(Domain, Type) -> {ok, Socket} | {error, Reason}
```

```
open(Domain, Type, Opts) -> {ok, Socket} | {error, Reason}
```

Types:

Domain = domain() \| integer()\
 Type = type() \| integer()\
 Opts = map()\
 Socket = socket()\
 Reason = posix() \| protocol\

Creates an endpoint (socket) for communication.

The same as *open(Domain, Type, default)* and *open(Domain, Type, default, Opts)* respectively.

```
open(Domain, Type, Protocol) -> {ok, Socket} | {error, Reason}
```

```
open(Domain, Type, Protocol, Opts) ->
        {ok, Socket} | {error, Reason}
```

Types:

Domain = domain() \| integer()\
 Type = type() \| integer()\
 Protocol = default \| protocol() \| integer()\
 Opts = \
\
     \#{netns =\> string(),\
\
       debug =\> boolean(),\
\
       use\_registry =\> boolean()}\
 Socket = socket()\
 Reason = posix() \| protocol\

Creates an endpoint (socket) for communication.

*Domain* and *Type* may be *integer()*s, as defined in the platform's header files. The same goes for *Protocol* as defined in the platform's *[services(5)](/services/5.md)* database. See also the OS man page for the library call *[socket(2)](/socket/2.md)*.

**Note:**

For some combinations of *Domain* and *Type* the platform has got a default protocol that can be selected with *Protocol = default*, and the platform may allow or require selecting the default protocol, a specific protocol, or either.

Examples:

- ***socket:open(inet, stream, tcp)*:**

  It is common that for protocol domain and type *inet,stream* it is allowed to select the *tcp* protocol although that mostly is the default.

- ***socket:open(local, dgram)*:**

  It is common that for the protocol domain *local* it is mandatory to not select a protocol, that is; to select the default protocol.

The *Opts* argument is intended for "other" options. The supported option(s) are described below:

- ***netns: string()*:**

  Used to set the network namespace during the open call. Only supported on the Linux platform.

- ***debug: boolean()*:**

  Enable or disable debug during the open call. \
   Defaults to *false*.

- ***use\_registry: boolean()*:**

  Enable or disable use of the socket registry for this socket. This overrides the global value. \
   Defaults to the global value, see *use\_registry/1*.

```
peername(Socket) -> {ok, SockAddr} | {error, Reason}
```

Types:

Socket = socket()\
 SockAddr = sockaddr\_recv()\
 Reason = posix() \| closed\

Returns the address of the peer connected to the socket.

```
recv(Socket) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

```
recv(Socket, Flags) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

```
recv(Socket, Length) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

```
recv(Socket, Flags, Timeout :: infinity) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

```
recv(Socket, Length, Flags) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

```
recv(Socket, Length, Timeout :: infinity) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

```
recv(Socket, Length, Flags, Timeout :: infinity) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

Types:

Socket = socket()\
 Length = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Data = binary()\
 Reason = posix() \| closed \| invalid()\

Receives data from a socket, waiting for it to arrive.

The argument *Length* specifies how many bytes to receive, with the special case *0* meaning "all available".

For a socket of type *stream* this call will not return until all requested data can be delivered, or if "all available" data was requested when the first data chunk arrives.

The message *Flags* may be symbolic *msg\_flag()*s and/or *integer()*s, as in the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

When there is a socket error this function returns *{error, Reason}*, or if some data arrived before the error; *{error, {Reason, Data}}*.

```
recv(Socket, Flags, Timeout :: integer() >= 0) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

```
recv(Socket, Length, Timeout :: integer() >= 0) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

```
recv(Socket, Length, Flags, Timeout :: integer() >= 0) ->
        {ok, Data} | {error, Reason} | {error, {Reason, Data}}
```

Types:

Socket = socket()\
 Length = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Data = binary()\
 Reason = posix() \| closed \| invalid() \| timeout\

Receives data from a socket, waiting at most *Timeout* milliseconds for it to arrive.

The same as  infinite time-out *recv/1,2,3,4* but returns *{error, timeout}* or *{error, {timeout, Data}}* after *Timeout* milliseconds, if the requested data has not been delivered.

```
recv(Socket, Flags, SelectHandle :: nowait) ->
        {ok, Data} |
        {select, SelectInfo} |
        {select, {SelectInfo, Data}} |
        {error, Reason} |
        {error, {Reason, Data}}
```

```
recv(Socket, Flags, SelectHandle :: select_handle()) ->
        {ok, Data} |
        {select, SelectInfo} |
        {select, {SelectInfo, Data}} |
        {error, Reason} |
        {error, {Reason, Data}}
```

```
recv(Socket, Length, SelectHandle :: nowait) ->
        {ok, Data} |
        {select, SelectInfo} |
        {select, {SelectInfo, Data}} |
        {error, Reason} |
        {error, {Reason, Data}}
```

```
recv(Socket, Length, SelectHandle :: select_handle()) ->
        {ok, Data} |
        {select, SelectInfo} |
        {select, {SelectInfo, Data}} |
        {error, Reason} |
        {error, {Reason, Data}}
```

```
recv(Socket, Length, Flags, SelectHandle :: nowait) ->
        {ok, Data} |
        {select, SelectInfo} |
        {select, {SelectInfo, Data}} |
        {error, Reason} |
        {error, {Reason, Data}}
```

```
recv(Socket, Length, Flags, SelectHandle :: select_handle()) ->
        {ok, Data} |
        {select, SelectInfo} |
        {select, {SelectInfo, Data}} |
        {error, Reason} |
        {error, {Reason, Data}}
```

Types:

Socket = socket()\
 Length = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Data = binary()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Receives data from a socket, but returns a select continuation if the data could not be returned immediately.

The same as  infinite time-out *recv/1,2,3,4* but if the data cannot be delivered immediately, the function returns *{select, SelectInfo}*, and the caller will then receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* contained in the *SelectInfo* ) when data has arrived. A subsequent call to *recv/1,2,3,4* will then return the data.

If the time-out argument is *SelectHandle*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If the time-out argument is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

Note that for a socket of type *stream*, if *Length \> 0* and only part of that amount of data is available, the function will return *{ok, {Data, SelectInfo* with partial data. If the caller doesn't want to wait for more data, it must immediately call *cancel/2* to cancel the operation.

```
recvfrom(Socket) -> {ok, {Source, Data}} | {error, Reason}
```

```
recvfrom(Socket, Flags) -> {ok, {Source, Data}} | {error, Reason}
```

```
recvfrom(Socket, BufSz) -> {ok, {Source, Data}} | {error, Reason}
```

```
recvfrom(Socket, Flags, Timeout :: infinity) ->
            {ok, {Source, Data}} | {error, Reason}
```

```
recvfrom(Socket, BufSz, Flags) ->
            {ok, {Source, Data}} | {error, Reason}
```

```
recvfrom(Socket, BufSz, Timeout :: infinity) ->
            {ok, {Source, Data}} | {error, Reason}
```

```
recvfrom(Socket, BufSz, Flags, Timeout :: infinity) ->
            {ok, {Source, Data}} | {error, Reason}
```

Types:

Socket = socket()\
 BufSz = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Source = sockaddr\_recv()\
 Data = binary()\
 Reason = posix() \| closed \| invalid()\

Receive a message from a socket, waiting for it to arrive.

The function returns when a message is received, or when there is a socket error. Argument *BufSz* specifies the number of bytes for the receive buffer. If the buffer size is too small, the message will be truncated.

If *BufSz* is not specified or *0*, a default buffer size is used, which can be set by *socket:setopt(Socket, {otp,recvbuf}, BufSz)*.

If it is impossible to know the appropriate buffer size, it may be possible to use the receive message flag *peek*. When this flag is used, the message is *not* "consumed" from the underlying buffers, so another *recvfrom/1,2,3,4* call is needed, possibly with an adjusted buffer size.

The message *Flags* may be symbolic *msg\_flag()*s and/or *integer()*s, as in the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

```
recvfrom(Socket, Flags, Timeout :: integer() >= 0) ->
            {ok, {Source, Data}} | {error, Reason}
```

```
recvfrom(Socket, BufSz, Timeout :: integer() >= 0) ->
            {ok, {Source, Data}} | {error, Reason}
```

```
recvfrom(Socket, BufSz, Flags, Timeout :: integer() >= 0) ->
            {ok, {Source, Data}} | {error, Reason}
```

Types:

Socket = socket()\
 BufSz = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Source = sockaddr\_recv()\
 Data = binary()\
 Reason = posix() \| closed \| invalid() \| timeout\

Receives a message from a socket, waiting at most *Timeout* milliseconds for it to arrive.

The same as  infinite time-out *recvfrom/1,2,3,4* but returns *{error, timeout}* after *Timeout* milliseconds, if no message has been delivered.

```
recvfrom(Socket, Flags, SelectHandle :: nowait) ->
            {ok, {Source, Data}} |
            {select, SelectInfo} |
            {error, Reason}
```

```
recvfrom(Socket, Flags, SelectHandle :: select_handle()) ->
            {ok, {Source, Data}} |
            {select, SelectInfo} |
            {error, Reason}
```

```
recvfrom(Socket, BufSz, SelectHandle :: nowait) ->
            {ok, {Source, Data}} |
            {select, SelectInfo} |
            {error, Reason}
```

```
recvfrom(Socket, BufSz, SelectHandle :: select_handle()) ->
            {ok, {Source, Data}} |
            {select, SelectInfo} |
            {error, Reason}
```

```
recvfrom(Socket, BufSz, Flags, SelectHandle :: nowait) ->
            {ok, {Source, Data}} |
            {select, SelectInfo} |
            {error, Reason}
```

```
recvfrom(Socket, BufSz, Flags, SelectHandle :: select_handle()) ->
            {ok, {Source, Data}} |
            {select, SelectInfo} |
            {error, Reason}
```

Types:

Socket = socket()\
 BufSz = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Source = sockaddr\_recv()\
 Data = binary()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Receives a message from a socket, but returns a select continuation if no message could be returned immediately.

The same as  infinite time-out *recvfrom/1,2,3,4* but if no message cannot delivered immediately, the function returns *{select, SelectInfo}*, and the caller will then receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* contained in the *SelectInfo* ) when data has arrived. A subsequent call to *recvfrom/1,2,3,4* will then return the message.

If the time-out argument is *SelectHandle*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If the time-out argument is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

If the caller doesn't want to wait for the data, it must immediately call *cancel/2* to cancel the operation.

```
recvmsg(Socket) -> {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, Flags) -> {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, Timeout :: infinity) ->
           {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, Flags, Timeout :: infinity) ->
           {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz) -> {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz, Timeout :: infinity) ->
           {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz, Flags, Timeout :: infinity) ->
           {ok, Msg} | {error, Reason}
```

Types:

Socket = socket()\
 BufSz = CtrlSz = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Msg = msg\_recv()\
 Reason = posix() \| closed \| invalid()\

Receive a message from a socket, waiting for it to arrive.

The function returns when a message is received, or when there is a socket error. Arguments *BufSz* and *CtrlSz* specifies the number of bytes for the receive buffer and the control message buffer. If the buffer size(s) is(are) too small, the message and/or control message list will be truncated.

If *BufSz* is not specified or *0*, a default buffer size is used, which can be set by *socket:setopt(Socket, {otp,recvbuf}, BufSz)*.  The same applies to *CtrlSz* and *socket:setopt(Socket, {otp,recvctrlbuf}, CtrlSz)*.

If it is impossible to know the appropriate buffer size, it may be possible to use the receive message flag *peek*. When this flag is used, the message is *not* "consumed" from the underlying buffers, so another *recvfrom/1,2,3,4,5* call is needed, possibly with an adjusted buffer size.

The message *Flags* may be symbolic *msg\_flag()*s and/or *integer()*s, as in the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

```
recvmsg(Socket, Timeout :: integer() >= 0) ->
           {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, Flags, Timeout :: integer() >= 0) ->
           {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz, Timeout :: integer() >= 0) ->
           {ok, Msg} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz, Flags,
        Timeout :: integer() >= 0) ->
           {ok, Msg} | {error, Reason}
```

Types:

Socket = socket()\
 BufSz = CtrlSz = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Msg = msg\_recv()\
 Reason = posix() \| closed \| invalid() \| timeout\

Receives a message from a socket, waiting at most *Timeout* milliseconds for it to arrive.

The same as recvmsg/1,2,3,4,5 but returns *{error, timeout}* after *Timeout* milliseconds, if no message has been delivered.

```
recvmsg(Socket, Timeout :: nowait) ->
           {ok, Msg} | {select, SelectInfo} | {error, Reason}
```

```
recvmsg(Socket, SelectHandle :: select_handle()) ->
           {ok, Msg} | {select, SelectInfo} | {error, Reason}
```

```
recvmsg(Socket, Flags, Timeout :: nowait) ->
           {ok, Msg} | {select, SelectInfo} | {error, Reason}
```

```
recvmsg(Socket, Flags, SelectHandle :: select_handle()) ->
           {ok, Msg} | {select, SelectInfo} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz, SelectHandle :: nowait) ->
           {ok, Msg} | {select, SelectInfo} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz, SelectHandle :: select_handle()) ->
           {ok, Msg} | {select, SelectInfo} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz, Flags, SelectHandle :: nowait) ->
           {ok, Msg} | {select, SelectInfo} | {error, Reason}
```

```
recvmsg(Socket, BufSz, CtrlSz, Flags,
        SelectHandle :: select_handle()) ->
           {ok, Msg} | {select, SelectInfo} | {error, Reason}
```

Types:

Socket = socket()\
 BufSz = CtrlSz = integer() \>= 0\
 Flags = \[msg\_flag() \| integer()\]\
 Msg = msg\_recv()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Receives a message from a socket, but returns a select continuation if no message could be returned immediately.

The same as  infinite time-out *recvfrom/1,2,3,4* but if no message cannot delivered immediately, the function returns *{select, SelectInfo}*, and the caller will then receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* contained in the *SelectInfo* ) when data has arrived. A subsequent call to *recvmsg/1,2,3,4,5* will then return the data.

If the time-out argument is *SelectHandle*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If the time-out argument is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

If the caller doesn't want to wait for the data, it must immediately call *cancel/2* to cancel the operation.

```
send(Socket, Data) ->
        ok |
        {ok, RestData} |
        {error, Reason} |
        {error, {Reason, RestData}}
```

```
send(Socket, Data, Flags) ->
        ok |
        {ok, RestData} |
        {error, Reason} |
        {error, {Reason, RestData}}
```

```
send(Socket, Data, Timeout :: infinity) ->
        ok |
        {ok, RestData} |
        {error, Reason} |
        {error, {Reason, RestData}}
```

```
send(Socket, Data, Flags, Timeout :: infinity) ->
        ok |
        {ok, RestData} |
        {error, Reason} |
        {error, {Reason, RestData}}
```

Types:

Socket = socket()\
 Data = iodata()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = binary()\
 Reason = posix() \| closed \| invalid()\

Sends data on a connected socket, waiting for it to be sent.

This call will not return until the *Data* has been accepted by the platform's network layer, or it reports an error.

The message *Flags* may be symbolic *msg\_flag()*s and/or *integer()*s, matching the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

The *Data*, if it is not a *binary()*, is copied into one before calling the platform network API, because a single buffer is required. A returned *RestData* is a sub binary of this data binary.

The return value indicates the result from the platform's network layer:

- ***ok*:**

  All data has been accepted.

- ***{ok, RestData}*:**

  Not all data has been accepted, but no error has been reported. *RestData* is the tail of *Data* that has not been accepted.

  This cannot happen for a socket of type *stream* where a partially successful send is retried until the data is either accepted or there is an error.

  For a socket of type *dgram* this should probably also not happen since a message that cannot be passed atomically should render an error.

  It is nevertheless possible for the platform's network layer to return this.

- ***{error, Reason}*:**

  An error has been reported and no data has been accepted. The *posix()* *Reasons* are from the platform's network layer. *closed* means that this socket library knows that the socket is closed, and *invalid()* means that something about an argument is invalid.

- ***{error, {Reason, RestData}}* :**

  An error has been reported but before that some data was accepted. *RestData* is the tail of *Data* that has not been accepted. See *{error, Reason}* above.

  This can only happen for a socket of type *stream* when a partially successful send is retried until there is an error.

```
send(Socket, Data, Timeout :: integer() >= 0) ->
        ok |
        {ok, RestData} |
        {error, Reason | timeout} |
        {error, {Reason | timeout, RestData}}
```

```
send(Socket, Data, Flags, Timeout :: integer() >= 0) ->
        ok |
        {ok, RestData} |
        {error, Reason | timeout} |
        {error, {Reason | timeout, RestData}}
```

Types:

Socket = socket()\
 Data = iodata()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = binary()\
 Reason = posix() \| closed \| invalid()\

Sends data on a connected socket, waiting at most *Timeout* milliseconds for it to be sent.

The same as  infinite time-out *send/2,3,4* but returns *{error, timeout}* or *{error, {timeout, RestData}}* after *Timeout* milliseconds, if no *Data* or only some of it was accepted by the platform's network layer.

```
send(Socket, Data, SelectHandle :: nowait) ->
        ok |
        {ok, RestData} |
        {select, SelectInfo} |
        {select, {SelectInfo, RestData}} |
        {error, Reason}
```

```
send(Socket, Data, SelectHandle :: select_handle()) ->
        ok |
        {ok, RestData} |
        {select, SelectInfo} |
        {select, {SelectInfo, RestData}} |
        {error, Reason}
```

```
send(Socket, Data, Flags, SelectHandle :: nowait) ->
        ok |
        {ok, RestData} |
        {select, SelectInfo} |
        {select, {SelectInfo, RestData}} |
        {error, Reason}
```

```
send(Socket, Data, Flags, SelectHandle :: select_handle()) ->
        ok |
        {ok, RestData} |
        {select, SelectInfo} |
        {select, {SelectInfo, RestData}} |
        {error, Reason}
```

Types:

Socket = socket()\
 Data = iodata()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = binary()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Sends data on a connected socket, but returns a select continuation if the data could not be sent immediately.

The same as  infinite time-out *send/2,3* but if the data is not immediately accepted by the platform network layer, the function returns *{select, SelectInfo}*, and the caller will then receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* that was contained in the *SelectInfo* ) when there is room for more data. A subsequent call to *send/2-4* will then send the data.

If *SelectHandle* is a *select\_handle()*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If *SelectHandle* is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

If some of the data was sent, the function will return  *{ok, {RestData, SelectInfo},*  which can only happen for a socket of type *stream*. If the caller does not want to wait to send the rest of the data, it should immediately cancel the operation with *cancel/2*.

```
send(Socket, Data, Cont) ->
        ok |
        {ok, RestData} |
        {error, Reason} |
        {error, {Reason, RestData}}
```

```
send(Socket, Data, Cont, Timeout :: infinity) ->
        ok |
        {ok, RestData} |
        {error, Reason} |
        {error, {Reason, RestData}}
```

```
send(Socket, Data, Cont, Timeout :: integer() >= 0) ->
        ok |
        {ok, RestData} |
        {error, Reason | timeout} |
        {error, {Reason | timeout, RestData}}
```

```
send(Socket, Data, Cont, SelectHandle :: nowait) ->
        ok |
        {ok, RestData} |
        {select, SelectInfo} |
        {select, {SelectInfo, RestData}} |
        {error, Reason}
```

```
send(Socket, Data, Cont, SelectHandle :: select_handle()) ->
        ok |
        {ok, RestData} |
        {select, SelectInfo} |
        {select, {SelectInfo, RestData}} |
        {error, Reason}
```

Types:

Socket = socket()\
 Data = iodata()\
 Cont = select\_info()\
 RestData = binary()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Continues sending data on a connected socket, where the send operation was initiated by *send/3,4* that returned a *SelectInfo* continuation. Otherwise like  infinite time-out *send/2,3,4* ,  limited time-out *send/3,4* or  nowait *send/3,4* respectively.

*Cont* is the *SelectInfo* that was returned from the previous *send()* call.

If *Data* is not a *binary()*, it will be copied into one, again.

The return value indicates the result from the platform's network layer. See *send/2,3,4* and nowait *send/3,4*.

```
sendmsg(Socket, Msg) ->
           ok |
           {ok, RestData} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Msg, Flags) ->
           ok |
           {ok, RestData} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Msg, Timeout :: infinity) ->
           ok |
           {ok, RestData} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Msg, Flags, Timeout :: infinity) ->
           ok |
           {ok, RestData} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

Types:

Socket = socket()\
 Msg = msg\_send()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = erlang:iovec()\
 Reason = posix() \| closed \| invalid()\

Sends a message on a socket, waiting for it to be sent.

The destination, if needed, that is: if the socket is *not* connected, is provided in *Msg*, which also contains the data to send as a list of binaries. *Msg* may also contain an list of optional control messages (depending on what the protocol and platform supports).

For a connected socket no address field should be present in *Msg*, the platform may return an error or ignore one.

The message data is given to to the platform's network layer in the form of an I/O vector without copying the content. If the number of elements in the I/O vector is larger than allowed on the platform (reported in the *iov\_max* field from info/0), on a socket of type *stream* the send is iterated over all elements, but for other socket types the call fails.

This call will not return until the data has been handed over to the platform's network layer, or when it reports an error.

The message *Flags* may be symbolic *msg\_flag()*s and/or *integer()*s, matching the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

The return value indicates the result from the platform's network layer. See *send/2,3,4*.

```
sendmsg(Socket, Msg, Timeout :: integer() >= 0) ->
           ok |
           {ok, RestData} |
           {error, Reason | timeout} |
           {error, {Reason | timeout, RestData}}
```

```
sendmsg(Socket, Msg, Flags, Timeout :: integer() >= 0) ->
           ok |
           {ok, RestData} |
           {error, Reason | timeout} |
           {error, {Reason | timeout, RestData}}
```

Types:

Socket = socket()\
 Msg = msg\_send()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = erlang:iovec()\
 Reason = posix() \| closed \| invalid()\

Sends a message on a socket, waiting at most *Timeout* milliseconds for it to be sent.

The same as  infinite time-out *sendmsg/2,3,4* but returns *{error, timeout}* or *{error, {timeout, RestData}}* after *Timeout* milliseconds, if no data or only some of it was accepted by the platform's network layer.

```
sendmsg(Socket, Msg, Timeout :: nowait) ->
           ok |
           {ok, RestData} |
           {select, SelectInfo} |
           {select, {SelectInfo, RestData}} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Msg, SelectHandle :: select_handle()) ->
           ok |
           {ok, RestData} |
           {select, SelectInfo} |
           {select, {SelectInfo, RestData}} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Msg, Flags, SelectHandle :: nowait) ->
           ok |
           {ok, RestData} |
           {select, SelectInfo} |
           {select, {SelectInfo, RestData}} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Msg, Flags, SelectHandle :: select_handle()) ->
           ok |
           {ok, RestData} |
           {select, SelectInfo} |
           {select, {SelectInfo, RestData}} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

Types:

Socket = socket()\
 Msg = msg\_send()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = erlang:iovec()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Sends a message on a socket, but returns a select continuation if the data could not be sent immediately.

The same as  infinity time-out *sendmsg/2,3* but if the data is not immediately accepted by the platform network layer, the function returns *{select, SelectInfo}*, and the caller will then receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* that was contained in the *SelectInfo* ) when there is room for more data. A subsequent call to *sendmsg/2-4* will then send the data.

If *SelectHandle*, is a *select\_handle()*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If *SelectHandle* is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

If some of the data was sent, the function will return  *{ok, {RestData, SelectInfo},*  which can only happen for a socket of type *stream*. If the caller does not want to wait to send the rest of the data, it should immediately cancel the operation with *cancel/2*.

```
sendmsg(Socket, Data, Cont) ->
           ok |
           {ok, RestData} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Data, Cont, Timeout :: infinity) ->
           ok |
           {ok, RestData} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Data, Cont, Timeout :: integer() >= 0) ->
           ok |
           {ok, RestData} |
           {error, Reason | timeout} |
           {error, {Reason | timeout, RestData}}
```

```
sendmsg(Socket, Data, Cont, SelectHandle :: nowait) ->
           ok |
           {ok, RestData} |
           {select, SelectInfo} |
           {select, {SelectInfo, RestData}} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

```
sendmsg(Socket, Data, Cont, SelectHandle :: select_handle()) ->
           ok |
           {ok, RestData} |
           {select, SelectInfo} |
           {select, {SelectInfo, RestData}} |
           {error, Reason} |
           {error, {Reason, RestData}}
```

Types:

Socket = socket()\
 Data = msg\_send() \| erlang:iovec()\
 Cont = select\_info()\
 RestData = erlang:iovec()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Continues sending a message data on a socket, where the send operation was initiated by *sendmsg/3,4* that returned a *SelectInfo* continuation. Otherwise like  infinite time-out *sendmsg/2,3,4* ,  limited time-out *sendmsg/3,4* or  nowait *sendmsg/3,4* respectively.

*Cont* is the *SelectInfo* that was returned from the previous *sendmsg()* call.

The return value indicates the result from the platform's network layer. See *send/2,3,4* and nowait *sendmsg/3,4*.

```
sendto(Socket, Data, Dest) ->
          ok |
          {ok, RestData} |
          {error, Reason} |
          {error, {Reason, RestData}}
```

```
sendto(Socket, Data, Dest, Flags) ->
          ok |
          {ok, RestData} |
          {error, Reason} |
          {error, {Reason, RestData}}
```

```
sendto(Socket, Data, Dest, Timeout :: infinity) ->
          ok |
          {ok, RestData} |
          {error, Reason} |
          {error, {Reason, RestData}}
```

```
sendto(Socket, Data, Dest, Flags, Timeout :: infinity) ->
          ok |
          {ok, RestData} |
          {error, Reason} |
          {error, {Reason, RestData}}
```

Types:

Socket = socket()\
 Data = iodata()\
 Dest = sockaddr()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = binary()\
 Reason = posix() \| closed \| invalid()\

Sends data on a socket, to the specified destination, waiting for it to be sent.

This call will not return until the data has been accepted by the platform's network layer, or it reports an error.

If this call is used on a connection mode socket or on a connected socket, the platforms's network layer may return an error or ignore the destination address.

The message *Flags* may be symbolic *msg\_flag()*s and/or *integer()*s, matching the platform's appropriate header files. The values of all symbolic flags and integers are or:ed together.

The return value indicates the result from the platform's network layer. See *send/2,3,4*.

```
sendto(Socket, Data, Dest, Timeout :: integer() >= 0) ->
          ok |
          {ok, RestData} |
          {error, Reason | timeout} |
          {error, {Reason | timeout, RestData}}
```

```
sendto(Socket, Data, Dest, Flags, Timeout :: integer() >= 0) ->
          ok |
          {ok, RestData} |
          {error, Reason | timeout} |
          {error, {Reason | timeout, RestData}}
```

Types:

Socket = socket()\
 Data = iodata()\
 Dest = sockaddr()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = binary()\
 Reason = posix() \| closed \| invalid()\

Sends data on a socket, waiting at most *Timeout* milliseconds for it to be sent.

The same as  infinite time-out *sendto/3,4,5* but returns *{error, timeout}* or *{error, {timeout, RestData}}* after *Timeout* milliseconds, if no *Data* or only some of it was accepted by the platform's network layer.

```
sendto(Socket, Data, Dest, SelectHandle :: nowait) ->
          ok |
          {ok, RestData} |
          {select, SelectInfo} |
          {select, {SelectInfo, RestData}} |
          {error, Reason}
```

```
sendto(Socket, Data, Dest, SelectHandle :: select_handle()) ->
          ok |
          {ok, RestData} |
          {select, SelectInfo} |
          {select, {SelectInfo, RestData}} |
          {error, Reason}
```

```
sendto(Socket, Data, Dest, Flags, SelectHandle :: nowait) ->
          ok |
          {ok, RestData} |
          {select, SelectInfo} |
          {select, {SelectInfo, RestData}} |
          {error, Reason}
```

```
sendto(Socket, Data, Dest, Flags, SelectHandle :: select_handle()) ->
          ok |
          {ok, RestData} |
          {select, SelectInfo} |
          {select, {SelectInfo, RestData}} |
          {error, Reason}
```

Types:

Socket = socket()\
 Data = iodata()\
 Dest = sockaddr()\
 Flags = \[msg\_flag() \| integer()\]\
 RestData = binary()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Sends data on a socket, but returns a select continuation if the data could not be sent immediately.

The same as  infinity time-out *sendto/3,4* but if the data is not immediately accepted by the platform network layer, the function returns *{select, SelectInfo}*, and the caller will then receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* that was contained in the *SelectInfo* ) when there is room for more data. A subsequent call to *sendto/3-5* will then send the data.

If *SelectHandle* is a *select\_handle()*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If *SelectHandle* is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

If some of the data was sent, the function will return  *{ok, {RestData, SelectInfo},*  which can only happen for a socket of type *stream*. If the caller does not want to wait to send the rest of the data, it should immediately cancel the operation with *cancel/2*.

```
sendto(Socket, Data, Cont) ->
          ok |
          {ok, RestData} |
          {error, Reason} |
          {error, {Reason, RestData}}
```

```
sendto(Socket, Data, Cont, Timeout :: infinity) ->
          ok |
          {ok, RestData} |
          {error, Reason} |
          {error, {Reason, RestData}}
```

```
sendto(Socket, Data, Cont, Timeout :: integer() >= 0) ->
          ok |
          {ok, RestData} |
          {error, Reason | timeout} |
          {error, {Reason | timeout, RestData}}
```

```
sendto(Socket, Data, Cont, SelectHandle :: nowait) ->
          ok |
          {ok, RestData} |
          {select, SelectInfo} |
          {select, {SelectInfo, RestData}} |
          {error, Reason}
```

```
sendto(Socket, Data, Cont, SelectHandle :: select_handle()) ->
          ok |
          {ok, RestData} |
          {select, SelectInfo} |
          {select, {SelectInfo, RestData}} |
          {error, Reason}
```

Types:

Socket = socket()\
 Data = iodata()\
 Cont = select\_info()\
 RestData = binary()\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Continues sending data on a socket, where the send operation was initiated by *sendto/4,5* that returned a *SelectInfo* continuation. Otherwise like  infinite time-out *sendto/3,4,5* ,  limited time-out *sendto/4,5* or  nowait *sendto/4,5* respectively.

*Cont* is the *SelectInfo* that was returned from the previous *sendto()* call.

If *Data* is not a *binary()*, it will be copied into one, again.

The return value indicates the result from the platform's network layer. See *send/2,3,4* and nowait *sendto/4,5*.

```
sendfile(Socket, FileHandle, Offset, Count, Timeout :: infinity) ->
            {ok, BytesSent} |
            {error, Reason} |
            {error, {Reason, BytesSent}}
```

Types:

Socket = socket()\
 FileHandle = file:fd()\
 Offset = integer()\
 Count = BytesSent = integer() \>= 0\
 Reason = posix() \| closed \| invalid()\

Sends file data on a socket, to the specified destination, waiting for it to be sent (*"infinite" time-out*).

The *FileHandle* must refer to an open raw file as described in *file:open/2*.

This call will not return until the data has been accepted by the platform's network layer, or it reports an error.

The *Offset* argument is the file offset to start reading from. The default value is *0*.

The *Count* argument is the number of bytes to transfer from *FileHandle* to *Socket*. If *Count =:= 0* (the default) the transfer stops at the end of file.

The return value indicates the result from the platform's network layer:

- ***{ok, BytesSent}*:**

  The transfer completed successfully after *BytesSent* bytes of data.

- ***{error, Reason}*:**

  An error has been reported and no data has been transferred. The *posix()* *Reasons* are from the platform's network layer. *closed* means that this socket library knows that the socket is closed, and *invalid()* means that something about an argument is invalid.

- ***{error, {Reason, BytesSent}}* :**

  An error has been reported but before that some data was transferred. See *{error, Reason}* and *{ok, BytesSent}* above.

```
sendfile(Socket, FileHandle, Offset, Count,
         Timeout :: integer() >= 0) ->
            {ok, BytesSent} |
            {error, Reason | timeout} |
            {error, {Reason | timeout, BytesSent}}
```

Types:

Socket = socket()\
 FileHandle = file:fd()\
 Offset = integer()\
 Count = BytesSent = integer() \>= 0\
 Reason = posix() \| closed \| invalid()\

Sends file data on a socket, waiting at most *Timeout* milliseconds for it to be sent (*limited time-out*).

The same as  "infinite" time-out *sendfile/5* but returns *{error, timeout}* or *{error, {timeout, BytesSent}}* after *Timeout* milliseconds, if not all file data was transferred by the platform's network layer.

```
sendfile(Socket, FileHandle, Offset, Count,
         SelectHandle :: nowait) ->
            {ok, BytesSent} |
            {select, SelectInfo} |
            {select, {SelectInfo, BytesSent}} |
            {error, Reason}
```

```
sendfile(Socket, FileHandle, Offset, Count,
         SelectHandle :: select_handle()) ->
            {ok, BytesSent} |
            {select, SelectInfo} |
            {select, {SelectInfo, BytesSent}} |
            {error, Reason}
```

Types:

Socket = socket()\
 FileHandle = file:fd()\
 Offset = integer()\
 Count = BytesSent = integer() \>= 0\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Sends file data on a socket, but returns a select continuation if the data could not be sent immediately (*nowait*).

The same as  "infinite" time-out *sendfile/5* but if the data is not immediately accepted by the platform network layer, the function returns *{select, SelectInfo}*, and the caller will then receive a select message, *{'$socket', Socket, select, SelectHandle}* ( with the *SelectHandle* that was contained in the *SelectInfo* ) when there is room for more data. Then a call to *sendfile/3* with *SelectInfo* as the second argument will continue the data transfer.

If *SelectHandle* is a *select\_handle()*, that term will be contained in a returned *SelectInfo* and the corresponding select message. The *SelectHandle* is presumed to be unique to this call.

If *SelectHandle* is *nowait*, and a *SelectInfo* is returned, it will contain a *select\_handle()* generated by the call.

If some file data was sent, the function will return  *{ok, {BytesSent, SelectInfo}.*  If the caller does not want to wait to send the rest of the data, it should immediately cancel the operation with *cancel/2*.

```
sendfile(Socket, Cont, Offset, Count, Timeout :: infinity) ->
            {ok, BytesSent} |
            {error, Reason} |
            {error, {Reason, BytesSent}}
```

```
sendfile(Socket, Cont, Offset, Count,
         Timeout :: integer() >= 0) ->
            {ok, BytesSent} |
            {error, Reason | timeout} |
            {error, {Reason | timeout, BytesSent}}
```

```
sendfile(Socket, Cont, Offset, Count, SelectHandle :: nowait) ->
            {ok, BytesSent} |
            {select, SelectInfo} |
            {select, {SelectInfo, BytesSent}} |
            {error, Reason}
```

```
sendfile(Socket, Cont, Offset, Count,
         SelectHandle :: select_handle()) ->
            {ok, BytesSent} |
            {select, SelectInfo} |
            {select, {SelectInfo, BytesSent}} |
            {error, Reason}
```

Types:

Socket = socket()\
 Cont = select\_info()\
 Offset = integer()\
 Count = BytesSent = integer() \>= 0\
 SelectInfo = select\_info()\
 Reason = posix() \| closed \| invalid()\

Continues sending file data on a socket, where the send operation was initiated by *sendfile/3,5* that returned a *SelectInfo* continuation. Otherwise like  "infinite" time-out *sendfile/5* ,  limited time-out *sendfile/5* or  nowait *sendfile/5* respectively.

*Cont* is the *SelectInfo* that was returned from the previous *sendfile()* call.

The return value indicates the result from the platform's network layer. See  "infinite" time-out *sendfile/5*.

**sendfile(Socket, FileHandle, Offset, Count) -\> Result**\

Types:

Socket = socket()\
 FileHandle = file:fd()\
 Offset = integer()\
 Count = integer() \>= 0\

The same as  *sendfile(Socket, FileHandle, Offset, Count, infinity),*  that is: send the file data at *Offset* and *Count* to the socket, without time-out other than from the platform's network stack.

**sendfile(Socket, FileHandle, Timeout) -\> Result**\

Types:

Socket = socket()\
 FileHandle = file:fd()\
\
  Timeout = timeout() \| 'nowait' \| select\_handle()\

Depending on the *Timeout* argument; the same as  *sendfile(Socket, FileHandle, 0, 0, infinity),*   *sendfile(Socket, FileHandle, 0, 0, Timeout),*  or  *sendfile(Socket, FileHandle, 0, 0, SelectHandle),*  that is: send all data in the file to the socket, with the given *Timeout*.

**sendfile(Socket, FileHandle) -\> Result**\

Types:

Socket = socket()\
 FileHandle = file:fd()\

The same as  *sendfile(Socket, FileHandle, 0, 0, infinity),*  that is: send all data in the file to the socket, without time-out other than from the platform's network stack.

```
setopt(Socket :: socket(),
       SocketOption :: {Level :: otp, Opt :: otp_socket_option()},
       Value :: term()) ->
          ok | {error, invalid() | closed}
```

Sets a socket option in the protocol level *otp*, which is this implementation's level above the OS protocol layers.

See the type  otp\_socket\_option()  for a description of the options on this level.

```
setopt(Socket :: socket(),
       SocketOption :: socket_option(),
       Value :: term()) ->
          ok | {error, posix() | invalid() | closed}
```

Set a socket option in one of the OS's protocol levels. See the type socket\_option() for which options that this implementation knows about, how they are related to option names in the OS, and if there are known peculiarities with any of them.

What options are valid depends on what kind of socket it is (*domain()*, *type()* and *protocol()*).

See the  socket options  chapter of the users guide for more info.

**Note:**

Not all options are valid, nor possible to set, on all platforms. That is, even if "we" support an option; it does not mean that the underlying OS does.

**setopt(Socket, Level, Opt, Value) -\> ok \| {error, Reason}**\

Types:

 Socket = socket()\
\
  Value = term() \
\
  Reason = inet:posix() \| *invalid()* \| closed \

Backwards compatibility function.

The same as *setopt(Socket, {Level, Opt}, Value)*

```
setopt_native(Socket :: socket(),
              SocketOption ::
                  socket_option() |
                  {Level :: level() | (NativeLevel :: integer()),
                   NativeOpt :: integer()},
              Value :: native_value()) ->
                 ok | {error, posix() | invalid() | closed}
```

Sets a socket option that may be unknown to our implementation, or that has a type not compatible with our implementation, that is; in "native mode".

If *Value* is an *integer()* it will be used as a *C* type *(int)*, if it is a *boolean()* it will be used as a *C* type *(int)* with the *C* implementations values for *false* or *true*, and if it is a *binary()* its content and size will be used as the option value.

The socket option may be specified with an ordinary *socket\_option()* tuple, with a known *Level = level()* and an integer *NativeOpt*, or with both an integer *NativeLevel* and *NativeOpt*.

What options are valid depends on what kind of socket it is (*domain()*, *type()* and *protocol()*).

The integer values for *NativeLevel* and *NativeOpt* as well as the encoding of *Value* has to be deduced from the header files for the running system.

```
shutdown(Socket, How) -> ok | {error, Reason}
```

Types:

Socket = socket()\
 How = read \| write \| read\_write\
 Reason = posix() \| closed\

Shut down all or part of a full-duplex connection.

```
sockname(Socket) -> {ok, SockAddr} | {error, Reason}
```

Types:

Socket = socket()\
 SockAddr = sockaddr\_recv()\
 Reason = posix() \| closed\

Returns the current address to which the socket is bound.

```
supports() ->
            [{Key1 :: term(),
              boolean() |
              [{Key2 :: term(),
                boolean() | [{Key3 :: term(), boolean()}]}]}]
```

```
supports(Key1 :: term()) ->
            [{Key2 :: term(),
              boolean() | [{Key3 :: term(), boolean()}]}]
```

```
supports(Key1 :: term(), Key2 :: term()) ->
            [{Key3 :: term(), boolean()}]
```

These functions function retrieves information about what the platform supports, such which platform features or which socket options, are supported.

For keys other than the known the empty list is returned, Note that in a future version or on a different platform there might be more supported items.

- ***supports()*:**

  Returns a list of *{Key1, supports(Key1)}* tuples for every *Key1* described in supports/1 and *{Key1, boolean()}* tuples for each of the following keys:

  - ***sctp*:**

    SCTP support

  - ***ipv6*:**

    IPv6 support

  - ***local*:**

     Unix Domain sockets support (*AF\_UNIX \| AF\_LOCAL*)

  - ***netns*:**

     Network Namespaces support (Linux, *[setns(2)](/setns/2.md)*)

  - ***sendfile*:**

     Sendfile support (*[sendfile(2)](/sendfile/2.md)*)

- ***supports(msg\_flags = Key1)*:**

  Returns a list of *{Flag, boolean()}* tuples for every *Flag* in *msg\_flag()* with the *boolean()* indicating if the flag is supported on this platform.

- ***supports(protocols = Key1)*:**

  Returns a list of *{Name :: atom(), boolean()}* tuples for every *Name* in *protocol()* with the *boolean()* indicating if the protocol is supported on this platform.

- ***supports(options = Key1)*:**

  Returns a list of *{SocketOption, boolean()}* tuples for every *SocketOption* in *socket\_option()* with the *boolean()* indicating if the socket option is supported on this platform.

- ***supports(options = Key1, Key2)* :**

  For a *Key2* in *level()* returns a list of *{Opt, boolean()}* tuples for all known  socket options *Opt* on that *Level =:= Key2*,  and the *boolean()* indicating if the socket option is supported on this platform. See setopt/3 and getopt/2.

```
use_registry(D :: boolean()) -> ok
```

Globally change if the socket registry is to be used or not. Note that its still possible to override this explicitly when creating an individual sockets, see *open/2* or *open/4* for more info (use the Extra argument).

```
which_sockets() -> [socket()]
```

```
which_sockets(FilterRule) -> [socket()]
```

Types:

FilterRule = \
\
     inet \| inet6 \| local \| stream \| dgram \| seqpacket \| sctp \|\
\
     tcp \| udp \|\
\
     pid() \|\
\
     fun((socket\_info()) -\> boolean())\

Returns a list of all sockets, according to the filter rule.

There are several pre-made filter rule(s) and one general:

- ***inet \| inet6*:**

  Selection based on the domain of the socket. \
   Only a subset is valid.

- ***stream \| dgram \| seqpacket*:**

  Selection based on the type of the socket. \
   Only a subset is valid.

- ***sctp \| tcp \| udp*:**

  Selection based on the protocol of the socket. \
   Only a subset is valid.

- ***pid()*:**

  Selection base on which sockets has this pid as Controlling Process.

- ***fun((socket\_info()) -\> boolean())*:**

  The general filter rule. \
   A fun that takes the socket info and returns a *boolean()* (*true* if the socket could be included and *false* if should not).

## EXAMPLES

```
client(SAddr, SPort) ->
   {ok, Sock} = socket:open(inet, stream, tcp),
   ok = socket:connect(Sock, #{family => inet,
                               addr   => SAddr,
                               port   => SPort}),
   Msg = <<"hello">>,
   ok = socket:send(Sock, Msg),
   ok = socket:shutdown(Sock, write),
   {ok, Msg} = socket:recv(Sock),
   ok = socket:close(Sock).
server(Addr, Port) ->
   {ok, LSock} = socket:open(inet, stream, tcp),
   ok = socket:bind(LSock, #{family => inet,
                             port   => Port,
                             addr   => Addr}),
   ok = socket:listen(LSock),
   {ok, Sock} = socket:accept(LSock),
   {ok, Msg} = socket:recv(Sock),
   ok = socket:send(Sock, Msg),
   ok = socket:close(Sock),
   ok = socket:close(LSock).
```
