Provided by: erlang-manpages_25.2.3+dfsg-1_all bug

NAME

       gen_tcp - Interface to TCP/IP sockets.

DESCRIPTION

       This module provides functions for communicating with sockets using the TCP/IP protocol.

       The following code fragment is a simple example of a client connecting to a server at port
       5678, transferring a binary, and closing the connection:

       client() ->
           SomeHostInNet = "localhost", % to make it runnable on one machine
           {ok, Sock} = gen_tcp:connect(SomeHostInNet, 5678,
                                        [binary, {packet, 0}]),
           ok = gen_tcp:send(Sock, "Some Data"),
           ok = gen_tcp:close(Sock).

       At the other end, a server is listening on port 5678, accepts the connection, and receives
       the binary:

       server() ->
           {ok, LSock} = gen_tcp:listen(5678, [binary, {packet, 0},
                                               {active, false}]),
           {ok, Sock} = gen_tcp:accept(LSock),
           {ok, Bin} = do_recv(Sock, []),
           ok = gen_tcp:close(Sock),
           ok = gen_tcp:close(LSock),
           Bin.

       do_recv(Sock, Bs) ->
           case gen_tcp:recv(Sock, 0) of
               {ok, B} ->
                   do_recv(Sock, [Bs, B]);
               {error, closed} ->
                   {ok, list_to_binary(Bs)}
           end.

       For more examples, see section Examples.

   Note:
       Functions  that  create sockets can take an optional option; {inet_backend, Backend} that,
       if specified, has to be the first option. This selects the implementation backend  towards
       the platform's socket API.

       This is a temporary option that will be ignored in a future release.

       The  default  is  Backend = inet that selects the traditional inet_drv.c driver. The other
       choice is Backend = socket that selects the new socket module and its NIF implementation.

       The system default can be changed when the node is started with the  application  kernel's
       configuration variable inet_backend.

       For  gen_tcp  with  inet_backend  = socket we have tried to be as "compatible" as possible
       which has sometimes been impossible. Here is a list of cases when the behaviour  of  inet-
       backend inet (default) and socket are different:

         * Non-blocking send

           If  a  user  calling  gen_tcp:send/2 with inet_backend = inet, tries to send more data
           than there is room for in the OS buffers, the "rest data"  is  buffered  by  the  inet
           driver (and later sent in the background). The effect for the user is that the call is
           non-blocking.

           This is not the effect when inet_backend  =  socket,  since  there  is  no  buffering.
           Instead the user hangs either until all data has been sent or the send_timeout timeout
           has been reached.

         * Remote close detected by background send.

           An background send will detect a 'remote close' and (the inet driver  will)  mark  the
           socket  as  'closed'.  No other action is taken. If the socket has active set to false
           (passive) at this point and no one is reading, this will not be noticed. But  as  soon
           as the socket is "activated" (active set to not false, send/2 is called or recv/2,3 is
           called), an error message will be sent to the caller or  (socket)  owner:  {tcp_error,
           Socket, econnreset}. Any data in the OS receive buffers will be lost!

           This  behaviour  is not replicated by the socket implementation. A send operation will
           detect a remote close and immediately return this to the caller, but do nothing  else.
           A reader will therefore be able to extract any data from the OS buffers. If the socket
           is set to active to not false, the data will be received as expected ({tcp,  ...}  and
           then a closed message ({tcp_closed, ...} will be received (not an error).

         * The  option  show_econnreset  basically  do  not  work  as  described  when  used with
           inet_backend = socket. The "issue" is that a remote  close  (as  described  above)  do
           allow a reader to extract what is in the read buffers before a close is "delivered".

         * The  option  nodelay  is  a  TCP  specific option that is not compatible with domain =
           local.

           When using inet_backend = socket, trying to create a socket (via  listen  or  connect)
           with  domain = local (for example with option {ifaddr, {local,"/tmp/test"}}) will fail
           with {error, enotsup}.

           This does not actually work for inet_backend = inet either, but in that case the error
           is  simply  ignored,  which is a bad idea. We have chosen to not ignore this error for
           inet_backend = socket.

         * Async shutdown write

           Calling  gen_tcp:shutdown(Socket,  write  |  read_write)  on  a  socket  created  with
           inet_backend  =  socket  will  take immediate effect, unlike for a socket created with
           inet_backend = inet.

           See async shutdown write for more info.

DATA TYPES

       option() =
           {active, true | false | once | -32768..32767} |
           {buffer, integer() >= 0} |
           {debug, boolean()} |
           {delay_send, boolean()} |
           {deliver, port | term} |
           {dontroute, boolean()} |
           {exit_on_close, boolean()} |
           {header, integer() >= 0} |
           {high_msgq_watermark, integer() >= 1} |
           {high_watermark, integer() >= 0} |
           {keepalive, boolean()} |
           {linger, {boolean(), integer() >= 0}} |
           {low_msgq_watermark, integer() >= 1} |
           {low_watermark, integer() >= 0} |
           {mode, list | binary} |
           list | binary |
           {nodelay, boolean()} |
           {packet,
            0 | 1 | 2 | 4 | raw | sunrm | asn1 | cdr | fcgi | line |
            tpkt | http | httph | http_bin | httph_bin} |
           {packet_size, integer() >= 0} |
           {priority, integer() >= 0} |
           {raw,
            Protocol :: integer() >= 0,
            OptionNum :: integer() >= 0,
            ValueBin :: binary()} |
           {recbuf, integer() >= 0} |
           {reuseaddr, boolean()} |
           {send_timeout, integer() >= 0 | infinity} |
           {send_timeout_close, boolean()} |
           {show_econnreset, boolean()} |
           {sndbuf, integer() >= 0} |
           {tos, integer() >= 0} |
           {tclass, integer() >= 0} |
           {ttl, integer() >= 0} |
           {recvtos, boolean()} |
           {recvtclass, boolean()} |
           {recvttl, boolean()} |
           {ipv6_v6only, boolean()}

       pktoptions_value() = {pktoptions, inet:ancillary_data()}

              If the platform implements the  IPv4  option  IP_PKTOPTIONS,  or  the  IPv6  option
              IPV6_PKTOPTIONS  or  IPV6_2292PKTOPTIONS for the socket this value is returned from
              inet:getopts/2 when called with the option name pktoptions.

          Note:
              This option appears to be VERY Linux specific, and its existence  in  future  Linux
              kernel  versions  is  also  worrying  since the option is part of RFC 2292 which is
              since long (2003) obsoleted by RFC 3542 that explicitly removes this possibility to
              get  packet  information  from  a  stream socket. For comparison: it has existed in
              FreeBSD but is now removed, at least since FreeBSD 10.

       option_name() =
           active | buffer | debug | delay_send | deliver | dontroute |
           exit_on_close | header | high_msgq_watermark |
           high_watermark | keepalive | linger | low_msgq_watermark |
           low_watermark | mode | nodelay | packet | packet_size |
           priority |
           {raw,
            Protocol :: integer() >= 0,
            OptionNum :: integer() >= 0,
            ValueSpec ::
                (ValueSize :: integer() >= 0) | (ValueBin :: binary())} |
           recbuf | reuseaddr | send_timeout | send_timeout_close |
           show_econnreset | sndbuf | tos | tclass | ttl | recvtos |
           recvtclass | recvttl | pktoptions | ipv6_v6only

       connect_option() =
           {fd, Fd :: integer() >= 0} |
           inet:address_family() |
           {ifaddr,
            socket:sockaddr_in() |
            socket:sockaddr_in6() |
            inet:socket_address()} |
           {ip, inet:socket_address()} |
           {port, inet:port_number()} |
           {tcp_module, module()} |
           {netns, file:filename_all()} |
           {bind_to_device, binary()} |
           option()

       listen_option() =
           {fd, Fd :: integer() >= 0} |
           inet:address_family() |
           {ifaddr,
            socket:sockaddr_in() |
            socket:sockaddr_in6() |
            inet:socket_address()} |
           {ip, inet:socket_address()} |
           {port, inet:port_number()} |
           {backlog, B :: integer() >= 0} |
           {tcp_module, module()} |
           {netns, file:filename_all()} |
           {bind_to_device, binary()} |
           option()

       socket()

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

EXPORTS

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

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

              Types:

                 ListenSocket = socket()
                   Returned by listen/2.
                 Timeout = timeout()
                 Socket = socket()
                 Reason = closed | timeout | system_limit | inet:posix()

              Accepts an incoming connection request on a listening  socket.  Socket  must  be  a
              socket  returned from listen/2. Timeout specifies a time-out value in milliseconds.
              Defaults to infinity.

              Returns:

                * {ok, Socket} if a connection is established

                * {error, closed} if ListenSocket is closed

                * {error, timeout} if no connection is established within the specified time

                * {error, system_limit} if all available ports in the Erlang emulator are in use

                * A POSIX error value if something else goes wrong, see inet(3erl)  for  possible
                  error values

              Packets  can  be sent to the returned socket Socket using send/2. Packets sent from
              the peer are delivered as messages (unless {active,  false}  is  specified  in  the
              option  list  for  the  listening  socket,  in  which case packets are retrieved by
              calling recv/2):

              {tcp, Socket, Data}

          Note:
              The accept call does not have to be issued from the  socket  owner  process.  Using
              version 5.5.3 and higher of the emulator, multiple simultaneous accept calls can be
              issued from different processes, which allows for  a  pool  of  acceptor  processes
              handling incoming connections.

       close(Socket) -> ok

              Types:

                 Socket = socket()

              Closes a TCP socket.

              Note that in most implementations of TCP, doing a close does not guarantee that any
              data sent is delivered to the recipient before the close is detected at the  remote
              side.  If you want to guarantee delivery of the data to the recipient there are two
              common ways to achieve this.

                * Use gen_tcp:shutdown(Sock, write) to signal that no more data is to be sent and
                  wait for the read side of the socket to be closed.

                * Use  the  socket  option {packet, N} (or something similar) to make it possible
                  for the receiver to close the connection when it knowns it has received all the
                  data.

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

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

              Types:

                 SockAddr = socket:sockaddr_in() | socket:sockaddr_in6()
                 Opts = [inet:inet_backend() | connect_option()]
                 Timeout = timeout()
                 Socket = socket()
                 Reason = timeout | inet:posix()

              Connects  to  a  server  according to SockAddr. This is primarily intended for link
              local IPv6 addresses (which require the scope-id), socket:sockaddr_in6().  But  for
              completeness, we also support IPv4, socket:sockaddr_in().

              The options available are the same as for connect/3,4.

          Note:
              Keep  in  mind  that  if  the  underlying  OS  connect()  call  returns  a timeout,
              gen_tcp:connect will also return a timeout (i.e. {error,  etimedout}),  even  if  a
              larger Timeout was specified.

          Note:
              The  default  values for options specified to connect can be affected by the Kernel
              configuration parameter inet_default_connect_options. For details, see inet(3erl).

       connect(Address, Port, Opts) -> {ok, Socket} | {error, Reason}

       connect(Address, Port, Opts, Timeout) ->
                  {ok, Socket} | {error, Reason}

              Types:

                 Address = inet:socket_address() | inet:hostname()
                 Port = inet:port_number()
                 Opts = [inet:inet_backend() | connect_option()]
                 Timeout = timeout()
                 Socket = socket()
                 Reason = timeout | inet:posix()

              Connects to a server on TCP port Port on the host with IP address Address. Argument
              Address can be a hostname or an IP address.

              The following options are available:

                {ip, Address}:
                  If  the  host  has  many network interfaces, this option specifies which one to
                  use.

                {ifaddr, Address}:
                  Same as {ip, Address}. If the host has many  network  interfaces,  this  option
                  specifies which one to use.

                  However,  if  this  instead is an socket:sockaddr_in() or socket:sockaddr_in6()
                  this takes precedence over any value  previously  set  with  the  ip  and  port
                  options.  If  these  options  (ip or/and port) however comes after this option,
                  they may be used to update their corresponding fields of this options (for  ip,
                  the addr field, and for port, the port field).

                {fd, integer() >= 0}:
                  If  a  socket has somehow been connected without using gen_tcp, use this option
                  to  pass  the  file  descriptor  for  it.  If  {ip,  Address}   and/or   {port,
                  port_number()}  is  combined with this option, the fd is bound to the specified
                  interface and port before connecting. If these options are not specified, it is
                  assumed that the fd is already bound appropriately.

                inet:
                  Sets up the socket for IPv4.

                inet6:
                  Sets up the socket for IPv6.

                local:
                  Sets up a Unix Domain Socket. See inet:local_address()

                {port, Port}:
                  Specifies which local port number to use.

                {tcp_module, module()}:
                  Overrides  which  callback  module  is  used. Defaults to inet_tcp for IPv4 and
                  inet6_tcp for IPv6.

                Opt:
                  See inet:setopts/2.

              Packets can be sent to the returned socket Socket using send/2. Packets  sent  from
              the peer are delivered as messages:

              {tcp, Socket, Data}

              If  the  socket  is  in  {active,  N} mode (see inet:setopts/2 for details) and its
              message counter drops to 0, the following message is delivered to indicate that the
              socket has transitioned to passive ({active, false}) mode:

              {tcp_passive, Socket}

              If the socket is closed, the following message is delivered:

              {tcp_closed, Socket}

              If  an  error  occurs  on  the  socket,  the following message is delivered (unless
              {active, false} is specified in the option list  for  the  socket,  in  which  case
              packets are retrieved by calling recv/2):

              {tcp_error, Socket, Reason}

              The  optional  Timeout  parameter specifies a time-out in milliseconds. Defaults to
              infinity.

          Note:
              Keep in  mind  that  if  the  underlying  OS  connect()  call  returns  a  timeout,
              gen_tcp:connect  will  also  return  a timeout (i.e. {error, etimedout}), even if a
              larger Timeout was specified.

          Note:
              The default values for options specified to connect can be affected by  the  Kernel
              configuration parameter inet_default_connect_options. For details, see inet(3erl).

       controlling_process(Socket, Pid) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 Pid = pid()
                 Reason = closed | not_owner | badarg | inet:posix()

              Assigns  a  new  controlling  process Pid to Socket. The controlling process is the
              process that receives messages from the socket. If called by any other process than
              the  current  controlling  process,  {error, not_owner} is returned. If the process
              identified by Pid is not an  existing  local  pid,  {error,  badarg}  is  returned.
              {error, badarg} may also be returned in some cases when Socket is closed during the
              execution of this function.

              If the socket is set in active mode, this function will transfer  any  messages  in
              the  mailbox  of the caller to the new controlling process. If any other process is
              interacting with the socket while the transfer is happening, the transfer  may  not
              work  correctly  and  messages  may  remain  in  the caller's mailbox. For instance
              changing the sockets active mode before the transfer is complete may cause this.

       listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}

              Types:

                 Port = inet:port_number()
                 Options = [inet:inet_backend() | listen_option()]
                 ListenSocket = socket()
                 Reason = system_limit | inet:posix()

              Sets up a socket to listen on port Port on the local host.

              If Port == 0, the underlying OS assigns an available port number,  use  inet:port/1
              to retrieve it.

              The following options are available:

                list:
                  Received Packet is delivered as a list.

                binary:
                  Received Packet is delivered as a binary.

                {backlog, B}:
                  B  is  an  integer  >= 0. The backlog value defines the maximum length that the
                  queue of pending connections can grow to. Defaults to 5.

                inet6:
                  Sets up the socket for IPv6.

                inet:
                  Sets up the socket for IPv4.

                {fd, Fd}:
                  If a socket has somehow been connected without using gen_tcp, use  this  option
                  to pass the file descriptor for it.

                {ip, Address}:
                  If  the  host  has  many network interfaces, this option specifies which one to
                  listen on.

                {port, Port}:
                  Specifies which local port number to use.

                {ifaddr, Address}:
                  Same as {ip, Address}. If the host has many  network  interfaces,  this  option
                  specifies which one to use.

                  However,  if  this  instead is an socket:sockaddr_in() or socket:sockaddr_in6()
                  this takes precedence over any value  previously  set  with  the  ip  and  port
                  options.  If  these  options  (ip or/and port) however comes after this option,
                  they may be used to update their corresponding fields of this options (for  ip,
                  the addr field, and for port, the port field).

                {tcp_module, module()}:
                  Overrides  which  callback  module  is  used. Defaults to inet_tcp for IPv4 and
                  inet6_tcp for IPv6.

                Opt:
                  See inet:setopts/2.

              The returned socket ListenSocket should be used in calls to  accept/1,2  to  accept
              incoming connection requests.

          Note:
              The  default  values  for options specified to listen can be affected by the Kernel
              configuration parameter inet_default_listen_options. For details, see inet(3erl).

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

       recv(Socket, Length, Timeout) -> {ok, Packet} | {error, Reason}

              Types:

                 Socket = socket()
                 Length = integer() >= 0
                 Timeout = timeout()
                 Packet = string() | binary() | HttpPacket
                 Reason = closed | timeout | inet:posix()
                 HttpPacket = term()
                   See the description of HttpPacket in erlang:decode_packet/3 in ERTS.

              Receives a packet from a socket in passive mode. A closed socket  is  indicated  by
              return value {error, closed}.

              Argument  Length  is only meaningful when the socket is in raw mode and denotes the
              number of bytes to read. If Length is 0,  all  available  bytes  are  returned.  If
              Length  >  0,  exactly  Length bytes are returned, or an error; possibly discarding
              less than Length bytes of data when the socket is closed from the other side.

              The optional Timeout parameter specifies a time-out in  milliseconds.  Defaults  to
              infinity.

       send(Socket, Packet) -> ok | {error, Reason}

              Types:

                 Socket = socket()
                 Packet = iodata()
                 Reason = closed | {timeout, RestData} | inet:posix()
                 RestData = binary()

              Sends a packet on a socket.

              There  is  no  send  call with a time-out option, use socket option send_timeout if
              time-outs are desired. See section Examples.

              The  return  value  {error,  {timeout,  RestData}}  can  only  be   returned   when
              inet_backend = socket.

          Note:
              Non-blocking send.

              If  the user tries to send more data than there is room for in the OS send buffers,
              the 'rest data' is put into (inet driver) internal buffers and later  sent  in  the
              background.  The function immediately returns ok (not informing the caller that not
              all of the data was actually sent). Any issue while  sending  the  'rest  data'  is
              maybe returned later.

              When using inet_backend = socket, the behaviour is different. There is no buffering
              done (like the inet-driver does), instead the caller will "hang" until all  of  the
              data  has  been  sent  or  send  timeout  (as specified by the send_timeout option)
              expires (the function can hang even when  using  'inet'  backend  if  the  internal
              buffers are full).

              If this happens when using packet =/= raw, we have a partial package written. A new
              package therefore must not be written at this point, as there is  no  way  for  the
              peer to distinguish this from the data portion of the current package. Instead, set
              package to raw, send the rest data (as raw data) and then set package to the wanted
              package type again.

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

              Types:

                 Socket = socket()
                 How = read | write | read_write
                 Reason = inet:posix()

              Closes a socket in one or two directions.

              How  ==  write  means  closing  the  socket  for  writing, reading from it is still
              possible.

              If How == read or there is no outgoing data buffered in the Socket port, the socket
              is shut down immediately and any error encountered is returned in Reason.

              If there is data buffered in the socket port, the attempt to shutdown the socket is
              postponed until that data is written to the  kernel  socket  send  buffer.  If  any
              errors are encountered, the socket is closed and {error, closed} is returned on the
              next recv/2 or send/2.

              Option {exit_on_close, false} is useful if the peer has  done  a  shutdown  on  the
              write side.

          Note:
              Async shutdown write (write or read_write).

              If  the  shutdown attempt is made while the inet-driver is sending buffered data in
              the background, the shutdown is postponed until all buffered data  has  been  sent.
              The  function  immediately  returns  ok  and  the  caller is not informed (that the
              shutdown has not yet been performed).

              When using inet_backend = socket, the behaviour is different. A shutdown  with  How
              ==  write  | read_write, the operation will take immediate effect (unlike the inet-
              driver, which basically saves the operation for later).

EXAMPLES

       The following example illustrates use of option  {active,once}  and  multiple  accepts  by
       implementing  a  server as a number of worker processes doing accept on a single listening
       socket. Function start/2 takes the number of worker processes and the port number on which
       to  listen  for incoming connections. If LPort is specified as 0, an ephemeral port number
       is used, which is why the start function returns the actual port number allocated:

       start(Num,LPort) ->
           case gen_tcp:listen(LPort,[{active, false},{packet,2}]) of
               {ok, ListenSock} ->
                   start_servers(Num,ListenSock),
                   {ok, Port} = inet:port(ListenSock),
                   Port;
               {error,Reason} ->
                   {error,Reason}
           end.

       start_servers(0,_) ->
           ok;
       start_servers(Num,LS) ->
           spawn(?MODULE,server,[LS]),
           start_servers(Num-1,LS).

       server(LS) ->
           case gen_tcp:accept(LS) of
               {ok,S} ->
                   loop(S),
                   server(LS);
               Other ->
                   io:format("accept returned ~w - goodbye!~n",[Other]),
                   ok
           end.

       loop(S) ->
           inet:setopts(S,[{active,once}]),
           receive
               {tcp,S,Data} ->
                   Answer = process(Data), % Not implemented in this example
                   gen_tcp:send(S,Answer),
                   loop(S);
               {tcp_closed,S} ->
                   io:format("Socket ~w closed [~w]~n",[S,self()]),
                   ok
           end.

       Example of a simple client:

       client(PortNo,Message) ->
           {ok,Sock} = gen_tcp:connect("localhost",PortNo,[{active,false},
                                                           {packet,2}]),
           gen_tcp:send(Sock,Message),
           A = gen_tcp:recv(Sock,0),
           gen_tcp:close(Sock),
           A.

       The send call does not accept a time-out option  because  time-outs  on  send  is  handled
       through  socket  option send_timeout. The behavior of a send operation with no receiver is
       mainly defined by the underlying TCP stack and the network infrastructure. To  write  code
       that  handles a hanging receiver that can eventually cause the sender to hang on a send do
       like the following.

       Consider a process that receives data from a client process to be forwarded to a server on
       the  network.  The  process is connected to the server through TCP/IP and does not get any
       acknowledge for each message it sends, but has to rely on  the  send  time-out  option  to
       detect  that  the  other  end  is  unresponsive.  Option  send_timeout  can  be  used when
       connecting:

       ...
       {ok,Sock} = gen_tcp:connect(HostAddress, Port,
                                   [{active,false},
                                    {send_timeout, 5000},
                                    {packet,2}]),
                       loop(Sock), % See below
       ...

       In the loop where requests are handled, send time-outs can now be detected:

       loop(Sock) ->
           receive
               {Client, send_data, Binary} ->
                   case gen_tcp:send(Sock,[Binary]) of
                       {error, timeout} ->
                           io:format("Send timeout, closing!~n",
                                     []),
                           handle_send_timeout(), % Not implemented here
                           Client ! {self(),{error_sending, timeout}},
                           %% Usually, it's a good idea to give up in case of a
                           %% send timeout, as you never know how much actually
                           %% reached the server, maybe only a packet header?!
                           gen_tcp:close(Sock);
                       {error, OtherSendError} ->
                           io:format("Some other error on socket (~p), closing",
                                     [OtherSendError]),
                           Client ! {self(),{error_sending, OtherSendError}},
                           gen_tcp:close(Sock);
                       ok ->
                           Client ! {self(), data_sent},
                           loop(Sock)
                   end
           end.

       Usually it suffices to detect time-outs on receive, as most protocols include some sort of
       acknowledgment  from  the  server,  but  if  the  protocol  is  strictly  one  way, option
       send_timeout comes in handy.