1gen_tcp(3) Erlang Module Definition gen_tcp(3)
2
3
4
6 gen_tcp - Interface to TCP/IP sockets.
7
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 not false, the data will be received as expected ({tcp,
91 ...} and then a closed message ({tcp_closed, ...} will be received
92 (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
118 * Windows require sockets (domain = inet | inet6) to be bound.
119
120 Currently all sockets created on Windows with inet_backend = socket
121 will be bound. If the user does not provide an address, gen_tcp
122 will try to 'figure out' an address itself.
123
125 option() =
126 {active, true | false | once | -32768..32767} |
127 {buffer, integer() >= 0} |
128 {debug, boolean()} |
129 {delay_send, boolean()} |
130 {deliver, port | term} |
131 {dontroute, boolean()} |
132 {exit_on_close, boolean()} |
133 {exclusiveaddruse, boolean()} |
134 {header, integer() >= 0} |
135 {high_msgq_watermark, integer() >= 1} |
136 {high_watermark, integer() >= 0} |
137 {keepalive, boolean()} |
138 {linger, {boolean(), integer() >= 0}} |
139 {low_msgq_watermark, integer() >= 1} |
140 {low_watermark, integer() >= 0} |
141 {mode, list | binary} |
142 list | binary |
143 {nodelay, boolean()} |
144 {packet,
145 0 | 1 | 2 | 4 | raw | sunrm | asn1 | cdr | fcgi | line |
146 tpkt | http | httph | http_bin | httph_bin} |
147 {packet_size, integer() >= 0} |
148 {priority, integer() >= 0} |
149 {raw,
150 Protocol :: integer() >= 0,
151 OptionNum :: integer() >= 0,
152 ValueBin :: binary()} |
153 {recbuf, integer() >= 0} |
154 {reuseaddr, boolean()} |
155 {reuseport, boolean()} |
156 {reuseport_lb, boolean()} |
157 {send_timeout, integer() >= 0 | infinity} |
158 {send_timeout_close, boolean()} |
159 {show_econnreset, boolean()} |
160 {sndbuf, integer() >= 0} |
161 {tos, integer() >= 0} |
162 {tclass, integer() >= 0} |
163 {ttl, integer() >= 0} |
164 {recvtos, boolean()} |
165 {recvtclass, boolean()} |
166 {recvttl, boolean()} |
167 {ipv6_v6only, boolean()}
168
169 pktoptions_value() = {pktoptions, inet:ancillary_data()}
170
171 If the platform implements the IPv4 option IP_PKTOPTIONS, or the
172 IPv6 option IPV6_PKTOPTIONS or IPV6_2292PKTOPTIONS for the
173 socket this value is returned from inet:getopts/2 when called
174 with the option name pktoptions.
175
176 Note:
177 This option appears to be VERY Linux specific, and its existence
178 in future Linux kernel versions is also worrying since the op‐
179 tion is part of RFC 2292 which is since long (2003) obsoleted by
180 RFC 3542 that explicitly removes this possibility to get packet
181 information from a stream socket. For comparison: it has existed
182 in FreeBSD but is now removed, at least since FreeBSD 10.
183
184
185 option_name() =
186 active | buffer | debug | delay_send | deliver | dontroute |
187 exit_on_close | exclusiveaddruse | header |
188 high_msgq_watermark | high_watermark | keepalive | linger |
189 low_msgq_watermark | low_watermark | mode | nodelay | packet |
190 packet_size | priority |
191 {raw,
192 Protocol :: integer() >= 0,
193 OptionNum :: integer() >= 0,
194 ValueSpec ::
195 (ValueSize :: integer() >= 0) | (ValueBin :: binary())} |
196 recbuf | reuseaddr | reuseport | reuseport_lb | send_timeout |
197 send_timeout_close | show_econnreset | sndbuf | tos | tclass |
198 ttl | recvtos | recvtclass | recvttl | pktoptions |
199 ipv6_v6only
200
201 connect_option() =
202 {fd, Fd :: integer() >= 0} |
203 inet:address_family() |
204 {ifaddr,
205 socket:sockaddr_in() |
206 socket:sockaddr_in6() |
207 inet:socket_address()} |
208 {ip, inet:socket_address()} |
209 {port, inet:port_number()} |
210 {tcp_module, module()} |
211 {netns, file:filename_all()} |
212 {bind_to_device, binary()} |
213 option()
214
215 listen_option() =
216 {fd, Fd :: integer() >= 0} |
217 inet:address_family() |
218 {ifaddr,
219 socket:sockaddr_in() |
220 socket:sockaddr_in6() |
221 inet:socket_address()} |
222 {ip, inet:socket_address()} |
223 {port, inet:port_number()} |
224 {backlog, B :: integer() >= 0} |
225 {tcp_module, module()} |
226 {netns, file:filename_all()} |
227 {bind_to_device, binary()} |
228 option()
229
230 socket()
231
232 As returned by accept/1,2 and connect/3,4.
233
235 accept(ListenSocket) -> {ok, Socket} | {error, Reason}
236
237 accept(ListenSocket, Timeout) -> {ok, Socket} | {error, Reason}
238
239 Types:
240
241 ListenSocket = socket()
242 Returned by listen/2.
243 Timeout = timeout()
244 Socket = socket()
245 Reason = closed | timeout | system_limit | inet:posix()
246
247 Accepts an incoming connection request on a listening socket.
248 Socket must be a socket returned from listen/2. Timeout speci‐
249 fies a time-out value in milliseconds. Defaults to infinity.
250
251 Returns:
252
253 * {ok, Socket} if a connection is established
254
255 * {error, closed} if ListenSocket is closed
256
257 * {error, timeout} if no connection is established within the
258 specified time
259
260 * {error, system_limit} if all available ports in the Erlang
261 emulator are in use
262
263 * A POSIX error value if something else goes wrong, see
264 inet(3) for possible error values
265
266 Packets can be sent to the returned socket Socket using send/2.
267 Packets sent from the peer are delivered as messages (unless
268 {active, false} is specified in the option list for the listen‐
269 ing socket, in which case packets are retrieved by calling
270 recv/2):
271
272 {tcp, Socket, Data}
273
274 Note:
275 The accept call does not have to be issued from the socket owner
276 process. Using version 5.5.3 and higher of the emulator, multi‐
277 ple simultaneous accept calls can be issued from different pro‐
278 cesses, which allows for a pool of acceptor processes handling
279 incoming connections.
280
281
282 close(Socket) -> ok
283
284 Types:
285
286 Socket = socket()
287
288 Closes a TCP socket.
289
290 Note that in most implementations of TCP, doing a close does not
291 guarantee that any data sent is delivered to the recipient be‐
292 fore the close is detected at the remote side. If you want to
293 guarantee delivery of the data to the recipient there are two
294 common ways to achieve this.
295
296 * Use gen_tcp:shutdown(Sock, write) to signal that no more
297 data is to be sent and wait for the read side of the socket
298 to be closed.
299
300 * Use the socket option {packet, N} (or something similar) to
301 make it possible for the receiver to close the connection
302 when it knowns it has received all the data.
303
304 connect(SockAddr, Opts) -> {ok, Socket} | {error, Reason}
305
306 connect(SockAddr, Opts, Timeout) -> {ok, Socket} | {error, Reason}
307
308 Types:
309
310 SockAddr = socket:sockaddr_in() | socket:sockaddr_in6()
311 Opts = [inet:inet_backend() | connect_option()]
312 Timeout = timeout()
313 Socket = socket()
314 Reason = timeout | inet:posix()
315
316 Connects to a server according to SockAddr. This is primarily
317 intended for link local IPv6 addresses (which require the scope-
318 id), socket:sockaddr_in6(). But for completeness, we also sup‐
319 port IPv4, socket:sockaddr_in().
320
321 The options available are the same as for connect/3,4.
322
323 Note:
324 Keep in mind that if the underlying OS connect() call returns a
325 timeout, gen_tcp:connect will also return a timeout (i.e. {er‐
326 ror, etimedout}), even if a larger Timeout was specified.
327
328
329 Note:
330 The default values for options specified to connect can be af‐
331 fected by the Kernel configuration parameter inet_default_con‐
332 nect_options. For details, see inet(3).
333
334
335 connect(Address, Port, Opts) -> {ok, Socket} | {error, Reason}
336
337 connect(Address, Port, Opts, Timeout) ->
338 {ok, Socket} | {error, Reason}
339
340 Types:
341
342 Address = inet:socket_address() | inet:hostname()
343 Port = inet:port_number()
344 Opts = [inet:inet_backend() | connect_option()]
345 Timeout = timeout()
346 Socket = socket()
347 Reason = timeout | inet:posix()
348
349 Connects to a server on TCP port Port on the host with IP ad‐
350 dress Address. Argument Address can be a hostname or an IP ad‐
351 dress.
352
353 The following options are available:
354
355 {ip, Address}:
356 If the host has many network interfaces, this option speci‐
357 fies which one to use.
358
359 {ifaddr, Address}:
360 Same as {ip, Address}. If the host has many network inter‐
361 faces, this option specifies which one to use.
362
363 However, if this instead is an socket:sockaddr_in() or
364 socket:sockaddr_in6() this takes precedence over any value
365 previously set with the ip and port options. If these op‐
366 tions (ip or/and port) however comes after this option, they
367 may be used to update their corresponding fields of this op‐
368 tions (for ip, the addr field, and for port, the port
369 field).
370
371 {fd, integer() >= 0}:
372 If a socket has somehow been connected without using
373 gen_tcp, use this option to pass the file descriptor for it.
374 If {ip, Address} and/or {port, port_number()} is combined
375 with this option, the fd is bound to the specified interface
376 and port before connecting. If these options are not speci‐
377 fied, it is assumed that the fd is already bound appropri‐
378 ately.
379
380 inet:
381 Sets up the socket for IPv4.
382
383 inet6:
384 Sets up the socket for IPv6.
385
386 local:
387 Sets up a Unix Domain Socket. See inet:local_address()
388
389 {port, Port}:
390 Specifies which local port number to use.
391
392 {tcp_module, module()}:
393 Overrides which callback module is used. Defaults to
394 inet_tcp for IPv4 and inet6_tcp for IPv6.
395
396 Opt:
397 See inet:setopts/2.
398
399 Packets can be sent to the returned socket Socket using send/2.
400 Packets sent from the peer are delivered as messages:
401
402 {tcp, Socket, Data}
403
404 If the socket is in {active, N} mode (see inet:setopts/2 for de‐
405 tails) and its message counter drops to 0, the following message
406 is delivered to indicate that the socket has transitioned to
407 passive ({active, false}) mode:
408
409 {tcp_passive, Socket}
410
411 If the socket is closed, the following message is delivered:
412
413 {tcp_closed, Socket}
414
415 If an error occurs on the socket, the following message is de‐
416 livered (unless {active, false} is specified in the option list
417 for the socket, in which case packets are retrieved by calling
418 recv/2):
419
420 {tcp_error, Socket, Reason}
421
422 The optional Timeout parameter specifies a time-out in millisec‐
423 onds. Defaults to infinity.
424
425 Note:
426 Keep in mind that if the underlying OS connect() call returns a
427 timeout, gen_tcp:connect will also return a timeout (i.e. {er‐
428 ror, etimedout}), even if a larger Timeout was specified.
429
430
431 Note:
432 The default values for options specified to connect can be af‐
433 fected by the Kernel configuration parameter inet_default_con‐
434 nect_options. For details, see inet(3).
435
436
437 controlling_process(Socket, Pid) -> ok | {error, Reason}
438
439 Types:
440
441 Socket = socket()
442 Pid = pid()
443 Reason = closed | not_owner | badarg | inet:posix()
444
445 Assigns a new controlling process Pid to Socket. The controlling
446 process is the process that receives messages from the socket.
447 If called by any other process than the current controlling
448 process, {error, not_owner} is returned. If the process identi‐
449 fied by Pid is not an existing local pid, {error, badarg} is re‐
450 turned. {error, badarg} may also be returned in some cases when
451 Socket is closed during the execution of this function.
452
453 If the socket is set in active mode, this function will transfer
454 any messages in the mailbox of the caller to the new controlling
455 process. If any other process is interacting with the socket
456 while the transfer is happening, the transfer may not work cor‐
457 rectly and messages may remain in the caller's mailbox. For in‐
458 stance changing the sockets active mode before the transfer is
459 complete may cause this.
460
461 listen(Port, Options) -> {ok, ListenSocket} | {error, Reason}
462
463 Types:
464
465 Port = inet:port_number()
466 Options = [inet:inet_backend() | listen_option()]
467 ListenSocket = socket()
468 Reason = system_limit | inet:posix()
469
470 Sets up a socket to listen on port Port on the local host.
471
472 If Port == 0, the underlying OS assigns an available port num‐
473 ber, use inet:port/1 to retrieve it.
474
475 The following options are available:
476
477 list:
478 Received Packet is delivered as a list.
479
480 binary:
481 Received Packet is delivered as a binary.
482
483 {backlog, B}:
484 B is an integer >= 0. The backlog value defines the maximum
485 length that the queue of pending connections can grow to.
486 Defaults to 5.
487
488 inet6:
489 Sets up the socket for IPv6.
490
491 inet:
492 Sets up the socket for IPv4.
493
494 {fd, Fd}:
495 If a socket has somehow been connected without using
496 gen_tcp, use this option to pass the file descriptor for it.
497
498 {ip, Address}:
499 If the host has many network interfaces, this option speci‐
500 fies which one to listen on.
501
502 {port, Port}:
503 Specifies which local port number to use.
504
505 {ifaddr, Address}:
506 Same as {ip, Address}. If the host has many network inter‐
507 faces, this option specifies which one to use.
508
509 However, if this instead is an socket:sockaddr_in() or
510 socket:sockaddr_in6() this takes precedence over any value
511 previously set with the ip and port options. If these op‐
512 tions (ip or/and port) however comes after this option, they
513 may be used to update their corresponding fields of this op‐
514 tions (for ip, the addr field, and for port, the port
515 field).
516
517 {tcp_module, module()}:
518 Overrides which callback module is used. Defaults to
519 inet_tcp for IPv4 and inet6_tcp for IPv6.
520
521 Opt:
522 See inet:setopts/2.
523
524 The returned socket ListenSocket should be used in calls to ac‐
525 cept/1,2 to accept incoming connection requests.
526
527 Note:
528 The default values for options specified to listen can be af‐
529 fected by the Kernel configuration parameter inet_default_lis‐
530 ten_options. For details, see inet(3).
531
532
533 recv(Socket, Length) -> {ok, Packet} | {error, Reason}
534
535 recv(Socket, Length, Timeout) -> {ok, Packet} | {error, Reason}
536
537 Types:
538
539 Socket = socket()
540 Length = integer() >= 0
541 Timeout = timeout()
542 Packet = string() | binary() | HttpPacket
543 Reason = closed | timeout | inet:posix()
544 HttpPacket = term()
545 See the description of HttpPacket in erlang:decode_packet/3
546 in ERTS.
547
548 Receives a packet from a socket in passive mode. A closed socket
549 is indicated by return value {error, closed}. If the socket is
550 not in passive mode, the return value is {error, einval}.
551
552 Argument Length is only meaningful when the socket is in raw
553 mode and denotes the number of bytes to read. If Length is 0,
554 all available bytes are returned. If Length > 0, exactly Length
555 bytes are returned, or an error; possibly discarding less than
556 Length bytes of data when the socket is closed from the other
557 side.
558
559 The optional Timeout parameter specifies a time-out in millisec‐
560 onds. Defaults to infinity.
561
562 Any process can receive data from a passive socket, even if that
563 process is not the controlling process of the socket. However,
564 only one process can call this function on a socket at any given
565 time. Using simultaneous calls to recv is not recommended as its
566 behavior is dependent on the socket implementation, and could
567 return errors such as {error, ealready}.
568
569 send(Socket, Packet) -> ok | {error, Reason}
570
571 Types:
572
573 Socket = socket()
574 Packet = iodata()
575 Reason = closed | {timeout, RestData} | inet:posix()
576 RestData = binary()
577
578 Sends a packet on a socket.
579
580 There is no send call with a time-out option, use socket option
581 send_timeout if time-outs are desired. See section Examples.
582
583 The return value {error, {timeout, RestData}} can only be re‐
584 turned when inet_backend = socket.
585
586 Note:
587 Non-blocking send.
588
589 If the user tries to send more data than there is room for in
590 the OS send buffers, the 'rest data' is put into (inet driver)
591 internal buffers and later sent in the background. The function
592 immediately returns ok (not informing the caller that not all of
593 the data was actually sent). Any issue while sending the 'rest
594 data' is maybe returned later.
595
596 When using inet_backend = socket, the behaviour is different.
597 There is no buffering done (like the inet-driver does), instead
598 the caller will "hang" until all of the data has been sent or
599 send timeout (as specified by the send_timeout option) expires
600 (the function can hang even when using 'inet' backend if the in‐
601 ternal buffers are full).
602
603 If this happens when using packet =/= raw, we have a partial
604 package written. A new package therefore must not be written at
605 this point, as there is no way for the peer to distinguish this
606 from the data portion of the current package. Instead, set pack‐
607 age to raw, send the rest data (as raw data) and then set pack‐
608 age to the wanted package type again.
609
610
611 shutdown(Socket, How) -> ok | {error, Reason}
612
613 Types:
614
615 Socket = socket()
616 How = read | write | read_write
617 Reason = inet:posix()
618
619 Closes a socket in one or two directions.
620
621 How == write means closing the socket for writing, reading from
622 it is still possible.
623
624 If How == read or there is no outgoing data buffered in the
625 Socket port, the socket is shut down immediately and any error
626 encountered is returned in Reason.
627
628 If there is data buffered in the socket port, the attempt to
629 shutdown the socket is postponed until that data is written to
630 the kernel socket send buffer. If any errors are encountered,
631 the socket is closed and {error, closed} is returned on the next
632 recv/2 or send/2.
633
634 Option {exit_on_close, false} is useful if the peer has done a
635 shutdown on the write side.
636
637 Note:
638 Async shutdown write (write or read_write).
639
640 If the shutdown attempt is made while the inet-driver is sending
641 buffered data in the background, the shutdown is postponed until
642 all buffered data has been sent. The function immediately re‐
643 turns ok and the caller is not informed (that the shutdown has
644 not yet been performed).
645
646 When using inet_backend = socket, the behaviour is different. A
647 shutdown with How == write | read_write, the operation will take
648 immediate effect (unlike the inet-driver, which basically saves
649 the operation for later).
650
651
653 The following example illustrates use of option {active,once} and mul‐
654 tiple accepts by implementing a server as a number of worker processes
655 doing accept on a single listening socket. Function start/2 takes the
656 number of worker processes and the port number on which to listen for
657 incoming connections. If LPort is specified as 0, an ephemeral port
658 number is used, which is why the start function returns the actual port
659 number allocated:
660
661 start(Num,LPort) ->
662 case gen_tcp:listen(LPort,[{active, false},{packet,2}]) of
663 {ok, ListenSock} ->
664 start_servers(Num,ListenSock),
665 {ok, Port} = inet:port(ListenSock),
666 Port;
667 {error,Reason} ->
668 {error,Reason}
669 end.
670
671 start_servers(0,_) ->
672 ok;
673 start_servers(Num,LS) ->
674 spawn(?MODULE,server,[LS]),
675 start_servers(Num-1,LS).
676
677 server(LS) ->
678 case gen_tcp:accept(LS) of
679 {ok,S} ->
680 loop(S),
681 server(LS);
682 Other ->
683 io:format("accept returned ~w - goodbye!~n",[Other]),
684 ok
685 end.
686
687 loop(S) ->
688 inet:setopts(S,[{active,once}]),
689 receive
690 {tcp,S,Data} ->
691 Answer = process(Data), % Not implemented in this example
692 gen_tcp:send(S,Answer),
693 loop(S);
694 {tcp_closed,S} ->
695 io:format("Socket ~w closed [~w]~n",[S,self()]),
696 ok
697 end.
698
699 Example of a simple client:
700
701 client(PortNo,Message) ->
702 {ok,Sock} = gen_tcp:connect("localhost",PortNo,[{active,false},
703 {packet,2}]),
704 gen_tcp:send(Sock,Message),
705 A = gen_tcp:recv(Sock,0),
706 gen_tcp:close(Sock),
707 A.
708
709 The send call does not accept a time-out option because time-outs on
710 send is handled through socket option send_timeout. The behavior of a
711 send operation with no receiver is mainly defined by the underlying TCP
712 stack and the network infrastructure. To write code that handles a
713 hanging receiver that can eventually cause the sender to hang on a send
714 do like the following.
715
716 Consider a process that receives data from a client process to be for‐
717 warded to a server on the network. The process is connected to the
718 server through TCP/IP and does not get any acknowledge for each message
719 it sends, but has to rely on the send time-out option to detect that
720 the other end is unresponsive. Option send_timeout can be used when
721 connecting:
722
723 {ok,Sock} = gen_tcp:connect(HostAddress, Port,
724 [{active,false},
725 {send_timeout, 5000},
726 {packet,2}]),
727 loop(Sock), % See below
728
729 In the loop where requests are handled, send time-outs can now be de‐
730 tected:
731
732 loop(Sock) ->
733 receive
734 {Client, send_data, Binary} ->
735 case gen_tcp:send(Sock,[Binary]) of
736 {error, timeout} ->
737 io:format("Send timeout, closing!~n",
738 []),
739 handle_send_timeout(), % Not implemented here
740 Client ! {self(),{error_sending, timeout}},
741 %% Usually, it's a good idea to give up in case of a
742 %% send timeout, as you never know how much actually
743 %% reached the server, maybe only a packet header?!
744 gen_tcp:close(Sock);
745 {error, OtherSendError} ->
746 io:format("Some other error on socket (~p), closing",
747 [OtherSendError]),
748 Client ! {self(),{error_sending, OtherSendError}},
749 gen_tcp:close(Sock);
750 ok ->
751 Client ! {self(), data_sent},
752 loop(Sock)
753 end
754 end.
755
756 Usually it suffices to detect time-outs on receive, as most protocols
757 include some sort of acknowledgment from the server, but if the proto‐
758 col is strictly one way, option send_timeout comes in handy.
759
760
761
762Ericsson AB kernel 9.1 gen_tcp(3)