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

EXPORTS

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

EXAMPLES

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