Provided by: erlang-manpages_24.2.1+dfsg-1ubuntu0.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 therefor 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 choosen 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} |
           {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 comparision: it has existed in
              FreeBSD but is now removed, at least since FreeBSD 10.

       option_name() =
           active | buffer | 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() =
           {ip, inet:socket_address()} |
           {fd, Fd :: integer() >= 0} |
           {ifaddr, inet:socket_address()} |
           inet:address_family() |
           {port, inet:port_number()} |
           {tcp_module, module()} |
           {netns, file:filename_all()} |
           {bind_to_device, binary()} |
           option()

       listen_option() =
           {ip, inet:socket_address()} |
           {fd, Fd :: integer() >= 0} |
           {ifaddr, inet:socket_address()} |
           inet:address_family() |
           {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(Address, Port, Options) -> {ok, Socket} | {error, Reason}

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

              Types:

                 Address = inet:socket_address() | inet:hostname()
                 Port = inet:port_number()
                 Options = [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.

                {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.

                {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.

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

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

                inet6:
                  Sets up the socket for IPv6.

                inet:
                  Sets up the socket for IPv4.

                {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 therefor 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.