1gen_tcp(3)                 Erlang Module Definition                 gen_tcp(3)
2
3
4

NAME

6       gen_tcp - Interface to TCP/IP sockets.
7

DESCRIPTION

9       This module provides functions for communicating with sockets using the
10       TCP/IP protocol.
11
12       The following code fragment is a simple example of a client  connecting
13       to  a  server at port 5678, transferring a binary, and closing the con‐
14       nection:
15
16       client() ->
17           SomeHostInNet = "localhost", % to make it runnable on one machine
18           {ok, Sock} = gen_tcp:connect(SomeHostInNet, 5678,
19                                        [binary, {packet, 0}]),
20           ok = gen_tcp:send(Sock, "Some Data"),
21           ok = gen_tcp:close(Sock).
22
23       At the other end, a server is listening on port 5678, accepts the  con‐
24       nection, and receives the binary:
25
26       server() ->
27           {ok, LSock} = gen_tcp:listen(5678, [binary, {packet, 0},
28                                               {active, false}]),
29           {ok, Sock} = gen_tcp:accept(LSock),
30           {ok, Bin} = do_recv(Sock, []),
31           ok = gen_tcp:close(Sock),
32           ok = gen_tcp:close(LSock),
33           Bin.
34
35       do_recv(Sock, Bs) ->
36           case gen_tcp:recv(Sock, 0) of
37               {ok, B} ->
38                   do_recv(Sock, [Bs, B]);
39               {error, closed} ->
40                   {ok, list_to_binary(Bs)}
41           end.
42
43       For more examples, see section Examples.
44
45   Note:
46       Functions  that create sockets can take an optional option; {inet_back‐
47       end, Backend} that, if specified, has to be the first option. This  se‐
48       lects the implementation backend towards the platform's socket API.
49
50       This is a temporary option that will be ignored in a future release.
51
52       The  default  is Backend = inet that selects the traditional inet_drv.c
53       driver. The other choice is Backend  =  socket  that  selects  the  new
54       socket module and its NIF implementation.
55
56       The system default can be changed when the node is started with the ap‐
57       plication kernel's configuration variable inet_backend.
58
59       For gen_tcp with inet_backend = socket we have tried to be as "compati‐
60       ble" as possible which has sometimes been impossible. Here is a list of
61       cases when the behaviour of inet-backend inet (default) and socket  are
62       different:
63
64         * Non-blocking send
65
66           If a user calling gen_tcp:send/2 with inet_backend = inet, tries to
67           send more data than there is room for in the OS buffers, the  "rest
68           data"  is  buffered by the inet driver (and later sent in the back‐
69           ground). The effect for the user is that the call is non-blocking.
70
71           This is not the effect when inet_backend = socket, since  there  is
72           no buffering. Instead the user hangs either until all data has been
73           sent or the send_timeout timeout has been reached.
74
75         * Remote close detected by background send.
76
77           An background send will detect  a  'remote  close'  and  (the  inet
78           driver will) mark the socket as 'closed'. No other action is taken.
79           If the socket has active set to false (passive) at this  point  and
80           no  one  is  reading,  this will not be noticed. But as soon as the
81           socket is "activated" (active set to not false, send/2 is called or
82           recv/2,3 is called), an error message will be sent to the caller or
83           (socket) owner: {tcp_error, Socket, econnreset}. Any data in the OS
84           receive buffers will be lost!
85
86           This  behaviour  is  not replicated by the socket implementation. A
87           send operation will detect a remote close  and  immediately  return
88           this  to the caller, but do nothing else. A reader will therefor be
89           able to extract any data from the OS buffers. If the socket is  set
90           to  active  to  not  false,  the  data will be received as expected
91           ({tcp, ...} and then a closed message ({tcp_closed,  ...}  will  be
92           received (not an error).
93
94         * The  option show_econnreset basically do not work as described when
95           used with inet_backend = socket. The "issue" is that a remote close
96           (as  described  above)  do allow a reader to extract what is in the
97           read buffers before a close is "delivered".
98
99         * The option nodelay is a TCP specific option that is not  compatible
100           with domain = local.
101
102           When  using  inet_backend  = socket, trying to create a socket (via
103           listen or connect) with domain = local  (for  example  with  option
104           {ifaddr, {local,"/tmp/test"}}) will fail with {error, enotsup}.
105
106           This  does not actually work for inet_backend = inet either, but in
107           that case the error is simply ignored, which is a bad idea. We have
108           choosen to not ignore this error for inet_backend = socket.
109
110         * Async shutdown write
111
112           Calling  gen_tcp:shutdown(Socket,  write  | read_write) on a socket
113           created with inet_backend = socket will take immediate effect,  un‐
114           like for a socket created with inet_backend = inet.
115
116           See async shutdown write for more info.
117

DATA TYPES

119       option() =
120           {active, true | false | once | -32768..32767} |
121           {buffer, integer() >= 0} |
122           {delay_send, boolean()} |
123           {deliver, port | term} |
124           {dontroute, boolean()} |
125           {exit_on_close, boolean()} |
126           {header, integer() >= 0} |
127           {high_msgq_watermark, integer() >= 1} |
128           {high_watermark, integer() >= 0} |
129           {keepalive, boolean()} |
130           {linger, {boolean(), integer() >= 0}} |
131           {low_msgq_watermark, integer() >= 1} |
132           {low_watermark, integer() >= 0} |
133           {mode, list | binary} |
134           list | binary |
135           {nodelay, boolean()} |
136           {packet,
137            0 | 1 | 2 | 4 | raw | sunrm | asn1 | cdr | fcgi | line |
138            tpkt | http | httph | http_bin | httph_bin} |
139           {packet_size, integer() >= 0} |
140           {priority, integer() >= 0} |
141           {raw,
142            Protocol :: integer() >= 0,
143            OptionNum :: integer() >= 0,
144            ValueBin :: binary()} |
145           {recbuf, integer() >= 0} |
146           {reuseaddr, boolean()} |
147           {send_timeout, integer() >= 0 | infinity} |
148           {send_timeout_close, boolean()} |
149           {show_econnreset, boolean()} |
150           {sndbuf, integer() >= 0} |
151           {tos, integer() >= 0} |
152           {tclass, integer() >= 0} |
153           {ttl, integer() >= 0} |
154           {recvtos, boolean()} |
155           {recvtclass, boolean()} |
156           {recvttl, boolean()} |
157           {ipv6_v6only, boolean()}
158
159       pktoptions_value() = {pktoptions, inet:ancillary_data()}
160
161              If the platform implements the IPv4 option IP_PKTOPTIONS, or the
162              IPv6  option  IPV6_PKTOPTIONS  or  IPV6_2292PKTOPTIONS  for  the
163              socket  this  value  is returned from inet:getopts/2 when called
164              with the option name pktoptions.
165
166          Note:
167              This option appears to be VERY Linux specific, and its existence
168              in  future  Linux kernel versions is also worrying since the op‐
169              tion is part of RFC 2292 which is since long (2003) obsoleted by
170              RFC  3542 that explicitly removes this possibility to get packet
171              information from a stream socket. For comparision:  it  has  ex‐
172              isted in FreeBSD but is now removed, at least since FreeBSD 10.
173
174
175       option_name() =
176           active | buffer | delay_send | deliver | dontroute |
177           exit_on_close | header | high_msgq_watermark |
178           high_watermark | keepalive | linger | low_msgq_watermark |
179           low_watermark | mode | nodelay | packet | packet_size |
180           priority |
181           {raw,
182            Protocol :: integer() >= 0,
183            OptionNum :: integer() >= 0,
184            ValueSpec ::
185                (ValueSize :: integer() >= 0) | (ValueBin :: binary())} |
186           recbuf | reuseaddr | send_timeout | send_timeout_close |
187           show_econnreset | sndbuf | tos | tclass | ttl | recvtos |
188           recvtclass | recvttl | pktoptions | ipv6_v6only
189
190       connect_option() =
191           {fd, Fd :: integer() >= 0} |
192           inet:address_family() |
193           {ifaddr,
194            socket:sockaddr_in() |
195            socket:sockaddr_in6() |
196            inet:socket_address()} |
197           {ip, inet:socket_address()} |
198           {port, inet:port_number()} |
199           {tcp_module, module()} |
200           {netns, file:filename_all()} |
201           {bind_to_device, binary()} |
202           option()
203
204       listen_option() =
205           {fd, Fd :: integer() >= 0} |
206           inet:address_family() |
207           {ifaddr,
208            socket:sockaddr_in() |
209            socket:sockaddr_in6() |
210            inet:socket_address()} |
211           {ip, inet:socket_address()} |
212           {port, inet:port_number()} |
213           {backlog, B :: integer() >= 0} |
214           {tcp_module, module()} |
215           {netns, file:filename_all()} |
216           {bind_to_device, binary()} |
217           option()
218
219       socket()
220
221              As returned by accept/1,2 and connect/3,4.
222

EXPORTS

224       accept(ListenSocket) -> {ok, Socket} | {error, Reason}
225
226       accept(ListenSocket, Timeout) -> {ok, Socket} | {error, Reason}
227
228              Types:
229
230                 ListenSocket = socket()
231                   Returned by listen/2.
232                 Timeout = timeout()
233                 Socket = socket()
234                 Reason = closed | timeout | system_limit | inet:posix()
235
236              Accepts  an  incoming  connection request on a listening socket.
237              Socket must be a socket returned from listen/2.  Timeout  speci‐
238              fies a time-out value in milliseconds. Defaults to infinity.
239
240              Returns:
241
242                * {ok, Socket} if a connection is established
243
244                * {error, closed} if ListenSocket is closed
245
246                * {error,  timeout} if no connection is established within the
247                  specified time
248
249                * {error, system_limit} if all available ports in  the  Erlang
250                  emulator are in use
251
252                * A  POSIX  error  value  if  something  else  goes wrong, see
253                  inet(3) for possible error values
254
255              Packets can be sent to the returned socket Socket using  send/2.
256              Packets  sent  from  the  peer are delivered as messages (unless
257              {active, false} is specified in the option list for the  listen‐
258              ing  socket,  in  which  case  packets  are retrieved by calling
259              recv/2):
260
261              {tcp, Socket, Data}
262
263          Note:
264              The accept call does not have to be issued from the socket owner
265              process.  Using version 5.5.3 and higher of the emulator, multi‐
266              ple simultaneous accept calls can be issued from different  pro‐
267              cesses,  which  allows for a pool of acceptor processes handling
268              incoming connections.
269
270
271       close(Socket) -> ok
272
273              Types:
274
275                 Socket = socket()
276
277              Closes a TCP socket.
278
279              Note that in most implementations of TCP, doing a close does not
280              guarantee  that  any data sent is delivered to the recipient be‐
281              fore the close is detected at the remote side. If  you  want  to
282              guarantee  delivery  of  the data to the recipient there are two
283              common ways to achieve this.
284
285                * Use gen_tcp:shutdown(Sock, write) to  signal  that  no  more
286                  data  is to be sent and wait for the read side of the socket
287                  to be closed.
288
289                * Use the socket option {packet, N} (or something similar)  to
290                  make  it  possible  for the receiver to close the connection
291                  when it knowns it has received all the data.
292
293       connect(SockAddr, Opts) -> {ok, Socket} | {error, Reason}
294
295       connect(SockAddr, Opts, Timeout) -> {ok, Socket} | {error, Reason}
296
297              Types:
298
299                 SockAddr = socket:sockaddr_in() | socket:sockaddr_in6()
300                 Opts = [inet:inet_backend() | connect_option()]
301                 Timeout = timeout()
302                 Socket = socket()
303                 Reason = timeout | inet:posix()
304
305              Connects to a server according to SockAddr.  This  is  primarily
306              intended for link local IPv6 addresses (which require the scope-
307              id), socket:sockaddr_in6(). But for completeness, we  also  sup‐
308              port IPv4, socket:sockaddr_in().
309
310              The options available are the same as for connect/3,4.
311
312          Note:
313              Keep  in mind that if the underlying OS connect() call returns a
314              timeout, gen_tcp:connect will also return a timeout  (i.e.  {er‐
315              ror, etimedout}), even if a larger Timeout was specified.
316
317
318          Note:
319              The  default  values for options specified to connect can be af‐
320              fected by the Kernel configuration  parameter  inet_default_con‐
321              nect_options. For details, see inet(3).
322
323
324       connect(Address, Port, Opts) -> {ok, Socket} | {error, Reason}
325
326       connect(Address, Port, Opts, Timeout) ->
327                  {ok, Socket} | {error, Reason}
328
329              Types:
330
331                 Address = inet:socket_address() | inet:hostname()
332                 Port = inet:port_number()
333                 Opts = [inet:inet_backend() | connect_option()]
334                 Timeout = timeout()
335                 Socket = socket()
336                 Reason = timeout | inet:posix()
337
338              Connects  to  a  server on TCP port Port on the host with IP ad‐
339              dress Address. Argument Address can be a hostname or an  IP  ad‐
340              dress.
341
342              The following options are available:
343
344                {ip, Address}:
345                  If  the host has many network interfaces, this option speci‐
346                  fies which one to use.
347
348                {ifaddr, Address}:
349                  Same as {ip, Address}. If the host has many  network  inter‐
350                  faces, this option specifies which one to use.
351
352                  However,  if  this  instead  is  an  socket:sockaddr_in() or
353                  socket:sockaddr_in6() this takes precedence over  any  value
354                  previously  set  with  the ip and port options. If these op‐
355                  tions (ip or/and port) however comes after this option, they
356                  may be used to update their corresponding fields of this op‐
357                  tions (for ip, the  addr  field,  and  for  port,  the  port
358                  field).
359
360                {fd, integer() >= 0}:
361                  If  a  socket  has  somehow  been  connected  without  using
362                  gen_tcp, use this option to pass the file descriptor for it.
363                  If  {ip,  Address}  and/or {port, port_number()} is combined
364                  with this option, the fd is bound to the specified interface
365                  and  port before connecting. If these options are not speci‐
366                  fied, it is assumed that the fd is already  bound  appropri‐
367                  ately.
368
369                inet:
370                  Sets up the socket for IPv4.
371
372                inet6:
373                  Sets up the socket for IPv6.
374
375                local:
376                  Sets up a Unix Domain Socket. See inet:local_address()
377
378                {port, Port}:
379                  Specifies which local port number to use.
380
381                {tcp_module, module()}:
382                  Overrides   which  callback  module  is  used.  Defaults  to
383                  inet_tcp for IPv4 and inet6_tcp for IPv6.
384
385                Opt:
386                  See inet:setopts/2.
387
388              Packets can be sent to the returned socket Socket using  send/2.
389              Packets sent from the peer are delivered as messages:
390
391              {tcp, Socket, Data}
392
393              If the socket is in {active, N} mode (see inet:setopts/2 for de‐
394              tails) and its message counter drops to 0, the following message
395              is  delivered  to  indicate  that the socket has transitioned to
396              passive ({active, false}) mode:
397
398              {tcp_passive, Socket}
399
400              If the socket is closed, the following message is delivered:
401
402              {tcp_closed, Socket}
403
404              If an error occurs on the socket, the following message  is  de‐
405              livered  (unless {active, false} is specified in the option list
406              for the socket, in which case packets are retrieved  by  calling
407              recv/2):
408
409              {tcp_error, Socket, Reason}
410
411              The optional Timeout parameter specifies a time-out in millisec‐
412              onds. Defaults to infinity.
413
414          Note:
415              Keep in mind that if the underlying OS connect() call returns  a
416              timeout,  gen_tcp:connect  will also return a timeout (i.e. {er‐
417              ror, etimedout}), even if a larger Timeout was specified.
418
419
420          Note:
421              The default values for options specified to connect can  be  af‐
422              fected  by  the Kernel configuration parameter inet_default_con‐
423              nect_options. For details, see inet(3).
424
425
426       controlling_process(Socket, Pid) -> ok | {error, Reason}
427
428              Types:
429
430                 Socket = socket()
431                 Pid = pid()
432                 Reason = closed | not_owner | badarg | inet:posix()
433
434              Assigns a new controlling process Pid to Socket. The controlling
435              process  is  the process that receives messages from the socket.
436              If called by any other  process  than  the  current  controlling
437              process,  {error, not_owner} is returned. If the process identi‐
438              fied by Pid is not an existing local pid, {error, badarg} is re‐
439              turned.  {error, badarg} may also be returned in some cases when
440              Socket is closed during the execution of this function.
441
442              If the socket is set in active mode, this function will transfer
443              any messages in the mailbox of the caller to the new controlling
444              process. If any other process is  interacting  with  the  socket
445              while  the transfer is happening, the transfer may not work cor‐
446              rectly and messages may remain in the caller's mailbox. For  in‐
447              stance  changing  the sockets active mode before the transfer is
448              complete may cause this.
449
450       listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}
451
452              Types:
453
454                 Port = inet:port_number()
455                 Options = [inet:inet_backend() | listen_option()]
456                 ListenSocket = socket()
457                 Reason = system_limit | inet:posix()
458
459              Sets up a socket to listen on port Port on the local host.
460
461              If Port == 0, the underlying OS assigns an available  port  num‐
462              ber, use inet:port/1 to retrieve it.
463
464              The following options are available:
465
466                list:
467                  Received Packet is delivered as a list.
468
469                binary:
470                  Received Packet is delivered as a binary.
471
472                {backlog, B}:
473                  B  is an integer >= 0. The backlog value defines the maximum
474                  length that the queue of pending connections  can  grow  to.
475                  Defaults to 5.
476
477                inet6:
478                  Sets up the socket for IPv6.
479
480                inet:
481                  Sets up the socket for IPv4.
482
483                {fd, Fd}:
484                  If  a  socket  has  somehow  been  connected  without  using
485                  gen_tcp, use this option to pass the file descriptor for it.
486
487                {ip, Address}:
488                  If the host has many network interfaces, this option  speci‐
489                  fies which one to listen on.
490
491                {port, Port}:
492                  Specifies which local port number to use.
493
494                {ifaddr, Address}:
495                  Same  as  {ip, Address}. If the host has many network inter‐
496                  faces, this option specifies which one to use.
497
498                  However, if  this  instead  is  an  socket:sockaddr_in()  or
499                  socket:sockaddr_in6()  this  takes precedence over any value
500                  previously set with the ip and port options.  If  these  op‐
501                  tions (ip or/and port) however comes after this option, they
502                  may be used to update their corresponding fields of this op‐
503                  tions  (for  ip,  the  addr  field,  and  for port, the port
504                  field).
505
506                {tcp_module, module()}:
507                  Overrides  which  callback  module  is  used.  Defaults   to
508                  inet_tcp for IPv4 and inet6_tcp for IPv6.
509
510                Opt:
511                  See inet:setopts/2.
512
513              The  returned socket ListenSocket should be used in calls to ac‐
514              cept/1,2 to accept incoming connection requests.
515
516          Note:
517              The default values for options specified to listen  can  be  af‐
518              fected  by  the Kernel configuration parameter inet_default_lis‐
519              ten_options. For details, see inet(3).
520
521
522       recv(Socket, Length) -> {ok, Packet} | {error, Reason}
523
524       recv(Socket, Length, Timeout) -> {ok, Packet} | {error, Reason}
525
526              Types:
527
528                 Socket = socket()
529                 Length = integer() >= 0
530                 Timeout = timeout()
531                 Packet = string() | binary() | HttpPacket
532                 Reason = closed | timeout | inet:posix()
533                 HttpPacket = term()
534                   See the description of HttpPacket in erlang:decode_packet/3
535                   in ERTS.
536
537              Receives a packet from a socket in passive mode. A closed socket
538              is indicated by return value {error, closed}.
539
540              Argument Length is only meaningful when the  socket  is  in  raw
541              mode  and  denotes  the number of bytes to read. If Length is 0,
542              all available bytes are returned. If Length > 0, exactly  Length
543              bytes  are  returned, or an error; possibly discarding less than
544              Length bytes of data when the socket is closed  from  the  other
545              side.
546
547              The optional Timeout parameter specifies a time-out in millisec‐
548              onds. Defaults to infinity.
549
550       send(Socket, Packet) -> ok | {error, Reason}
551
552              Types:
553
554                 Socket = socket()
555                 Packet = iodata()
556                 Reason = closed | {timeout, RestData} | inet:posix()
557                 RestData = binary()
558
559              Sends a packet on a socket.
560
561              There is no send call with a time-out option, use socket  option
562              send_timeout if time-outs are desired. See section Examples.
563
564              The  return  value  {error, {timeout, RestData}} can only be re‐
565              turned when inet_backend = socket.
566
567          Note:
568              Non-blocking send.
569
570              If the user tries to send more data than there is  room  for  in
571              the  OS  send buffers, the 'rest data' is put into (inet driver)
572              internal buffers and later sent in the background. The  function
573              immediately returns ok (not informing the caller that not all of
574              the data was actually sent). Any issue while sending  the  'rest
575              data' is maybe returned later.
576
577              When  using  inet_backend  = socket, the behaviour is different.
578              There is no buffering done (like the inet-driver does),  instead
579              the  caller  will  "hang" until all of the data has been sent or
580              send timeout (as specified by the send_timeout  option)  expires
581              (the function can hang even when using 'inet' backend if the in‐
582              ternal buffers are full).
583
584              If this happens when using packet =/= raw,  we  have  a  partial
585              package  written.  A new package therefor must not be written at
586              this point, as there is no way for the peer to distinguish  this
587              from the data portion of the current package. Instead, set pack‐
588              age to raw, send the rest data (as raw data) and then set  pack‐
589              age to the wanted package type again.
590
591
592       shutdown(Socket, How) -> ok | {error, Reason}
593
594              Types:
595
596                 Socket = socket()
597                 How = read | write | read_write
598                 Reason = inet:posix()
599
600              Closes a socket in one or two directions.
601
602              How  == write means closing the socket for writing, reading from
603              it is still possible.
604
605              If How == read or there is no  outgoing  data  buffered  in  the
606              Socket  port,  the socket is shut down immediately and any error
607              encountered is returned in Reason.
608
609              If there is data buffered in the socket  port,  the  attempt  to
610              shutdown  the  socket is postponed until that data is written to
611              the kernel socket send buffer. If any  errors  are  encountered,
612              the socket is closed and {error, closed} is returned on the next
613              recv/2 or send/2.
614
615              Option {exit_on_close, false} is useful if the peer has  done  a
616              shutdown on the write side.
617
618          Note:
619              Async shutdown write (write or read_write).
620
621              If the shutdown attempt is made while the inet-driver is sending
622              buffered data in the background, the shutdown is postponed until
623              all  buffered  data  has been sent. The function immediately re‐
624              turns ok and the caller is not informed (that the  shutdown  has
625              not yet been performed).
626
627              When  using inet_backend = socket, the behaviour is different. A
628              shutdown with How == write | read_write, the operation will take
629              immediate  effect (unlike the inet-driver, which basically saves
630              the operation for later).
631
632

EXAMPLES

634       The following example illustrates use of option {active,once} and  mul‐
635       tiple  accepts by implementing a server as a number of worker processes
636       doing accept on a single listening socket. Function start/2  takes  the
637       number  of  worker processes and the port number on which to listen for
638       incoming connections. If LPort is specified as  0,  an  ephemeral  port
639       number is used, which is why the start function returns the actual port
640       number allocated:
641
642       start(Num,LPort) ->
643           case gen_tcp:listen(LPort,[{active, false},{packet,2}]) of
644               {ok, ListenSock} ->
645                   start_servers(Num,ListenSock),
646                   {ok, Port} = inet:port(ListenSock),
647                   Port;
648               {error,Reason} ->
649                   {error,Reason}
650           end.
651
652       start_servers(0,_) ->
653           ok;
654       start_servers(Num,LS) ->
655           spawn(?MODULE,server,[LS]),
656           start_servers(Num-1,LS).
657
658       server(LS) ->
659           case gen_tcp:accept(LS) of
660               {ok,S} ->
661                   loop(S),
662                   server(LS);
663               Other ->
664                   io:format("accept returned ~w - goodbye!~n",[Other]),
665                   ok
666           end.
667
668       loop(S) ->
669           inet:setopts(S,[{active,once}]),
670           receive
671               {tcp,S,Data} ->
672                   Answer = process(Data), % Not implemented in this example
673                   gen_tcp:send(S,Answer),
674                   loop(S);
675               {tcp_closed,S} ->
676                   io:format("Socket ~w closed [~w]~n",[S,self()]),
677                   ok
678           end.
679
680       Example of a simple client:
681
682       client(PortNo,Message) ->
683           {ok,Sock} = gen_tcp:connect("localhost",PortNo,[{active,false},
684                                                           {packet,2}]),
685           gen_tcp:send(Sock,Message),
686           A = gen_tcp:recv(Sock,0),
687           gen_tcp:close(Sock),
688           A.
689
690       The send call does not accept a time-out option  because  time-outs  on
691       send  is  handled through socket option send_timeout. The behavior of a
692       send operation with no receiver is mainly defined by the underlying TCP
693       stack  and  the  network  infrastructure.  To write code that handles a
694       hanging receiver that can eventually cause the sender to hang on a send
695       do like the following.
696
697       Consider  a process that receives data from a client process to be for‐
698       warded to a server on the network. The  process  is  connected  to  the
699       server through TCP/IP and does not get any acknowledge for each message
700       it sends, but has to rely on the send time-out option  to  detect  that
701       the  other  end  is  unresponsive. Option send_timeout can be used when
702       connecting:
703
704       {ok,Sock} = gen_tcp:connect(HostAddress, Port,
705                                   [{active,false},
706                                    {send_timeout, 5000},
707                                    {packet,2}]),
708                       loop(Sock), % See below
709
710       In the loop where requests are handled, send time-outs can now  be  de‐
711       tected:
712
713       loop(Sock) ->
714           receive
715               {Client, send_data, Binary} ->
716                   case gen_tcp:send(Sock,[Binary]) of
717                       {error, timeout} ->
718                           io:format("Send timeout, closing!~n",
719                                     []),
720                           handle_send_timeout(), % Not implemented here
721                           Client ! {self(),{error_sending, timeout}},
722                           %% Usually, it's a good idea to give up in case of a
723                           %% send timeout, as you never know how much actually
724                           %% reached the server, maybe only a packet header?!
725                           gen_tcp:close(Sock);
726                       {error, OtherSendError} ->
727                           io:format("Some other error on socket (~p), closing",
728                                     [OtherSendError]),
729                           Client ! {self(),{error_sending, OtherSendError}},
730                           gen_tcp:close(Sock);
731                       ok ->
732                           Client ! {self(), data_sent},
733                           loop(Sock)
734                   end
735           end.
736
737       Usually  it  suffices to detect time-outs on receive, as most protocols
738       include some sort of acknowledgment from the server, but if the  proto‐
739       col is strictly one way, option send_timeout comes in handy.
740
741
742
743Ericsson AB                      kernel 8.3.2                       gen_tcp(3)
Impressum