15.3.1 TCP (original) (raw)

15.3.1 TCP🔗

The bindings documented in this section are provided by the racket/tcp and racket libraries, but not racket/base.

For information about TCP in general, see TCP/IP Illustrated, Volume 1 by W. Richard Stevens.

Creates a “listening” server on the local machine at the port number specified by port-no. If port-no is 0 the socket binds to an ephemeral port, which can be determined by callingtcp-addresses. The max-allow-wait argument determines the maximum number of client connections that can be waiting for acceptance. (When max-allow-wait clients are awaiting acceptance, no new client connections can be made.)

If the reuse? argument is true, then tcp-listen will create a listener even if the port is involved in a TIME_WAITstate. Such a use of reuse? defeats certain guarantees of the TCP protocol; see Stevens’s book for details. Furthermore, on many modern platforms, a true value for reuse? overridesTIME_WAIT only if the listener was previously created with a true value for reuse?.

If hostname is #f (the default), then the listener accepts connections to all of the listening machine’s addresses. Otherwise, the listener accepts connections only at the interface(s) associated with the given hostname. For example, providing"127.0.0.1" as hostname creates a listener that accepts only connections to "127.0.0.1" (the loopback interface) from the local machine.

Racket implements a listener with multiple sockets, if necessary, to accommodate multiple addresses with different protocol families. On Linux, if hostname maps to both IPv4 and IPv6 addresses, then the behavior depends on whether IPv6 is supported and IPv6 sockets can be configured to listen to only IPv6 connections: if IPv6 is not supported or IPv6 sockets are not configurable, then the IPv6 addresses are ignored; otherwise, each IPv6 listener accepts only IPv6 connections.

On variants of Unix and MacOS that support FD_CLOEXEC, a listener socket is given that flag so that it is not shared with a subprocess created by subprocess.

The return value of tcp-listen is a TCP listener. This value can be used in future calls totcp-accept, tcp-accept-ready?, andtcp-close. Each new TCP listener value is placed into the management of the current custodian (see Custodians).

If the server cannot be started by tcp-listen, theexn:fail:network exception is raised.

A TCP listener can be used as a synchronizable event (see Events). A TCP listener is ready for synchronization whentcp-accept would not block; the synchronization result of a TCP listener is the TCP listener itself.

Changed in version 8.11.1.6 of package base: Changed to use FD_CLOEXECwhere supported by the operating system.

(tcp-connect hostname port-no [local-hostname local-port-no]) →
hostname : string?
port-no : port-number?
local-hostname : (or/c string? #f) = #f
local-port-no : (or/c port-number? #f) = #f

Attempts to connect as a client to a listening server. Thehostname argument is the server host’s Internet address name, and port-no is the port number where the server is listening.

(If hostname is associated with multiple addresses, they are tried one at a time until a connection succeeds. The name"localhost" generally specifies the local machine.)

The optional local-hostname and local-port-nospecify the client’s address and port. If both are #f (the default), the client’s address and port are selected automatically. Iflocal-hostname is not #f, thenlocal-port-no must be non-#f. Iflocal-port-no is non-#f and local-hostnameis #f, then the given port is used but the address is selected automatically.

Two values are returned by tcp-connect: an input port and an output port. Data can be received from the server through the input port and sent to the server through the output port. If the server is a Racket program, it can obtain ports to communicate to the client with tcp-accept. These ports are placed into the management of the current custodian (see Custodians).

Initially, the returned input port is block-buffered, and the returned output port is block-buffered. Change the buffer mode usingfile-stream-buffer-mode. When a TCP output port is block-buffered, Nagle’s algorithm is disabled for the port, which corresponds to setting the TCP_NODELAY socket option.

Both of the returned ports must be closed to terminate the TCP connection. When both ports are still open, closing the output port with close-output-port sends a TCP close to the server (which is seen as an end-of-file if the server reads the connection through a port). In contrast, tcp-abandon-port (see below) closes the output port, but does not send a TCP close until the input port is also closed.

Note that the TCP protocol does not support a state where one end is willing to send but not read, nor does it include an automatic message when one end of a connection is fully closed. Instead, the other end of a connection discovers that one end is fully closed only as a response to sending data; in particular, some number of writes on the still-open end may appear to succeed, though writes will eventually produce an error.

On variants of Unix and MacOS that support FD_CLOEXEC, a connection socket is given that flag so that it is not shared with a subprocess created by subprocess.

If a connection cannot be established by tcp-connect, theexn:fail:network exception is raised.

Changed in version 8.8.0.8 of package base: Changed block buffering to implyTCP_NODELAY.
Changed in version 8.11.1.6: Changed to use FD_CLOEXECwhere supported by the operating system.

(tcp-connect/enable-break hostname port-no [local-hostname] local-port-no)
hostname : string?
port-no : port-number?
local-hostname : (or/c string? #f) = #f
local-port-no : (or/c port-number? #f)

Like tcp-connect, but breaking is enabled (seeBreaks) while trying to connect. If breaking is disabled when tcp-connect/enable-break is called, then either ports are returned or the exn:break exception is raised, but not both.

Accepts a client connection for the server associated withlistener. If no client connection is waiting on the listening port, the call to tcp-accept will block. (See alsotcp-accept-ready?.)

Two values are returned by tcp-accept: an input port and an output port. Data can be received from the client through the input port and sent to the client through the output port. These ports are placed into the management of the current custodian (seeCustodians).

In terms of buffering and connection states, the ports act the same as ports from tcp-connect.

On variants of Unix and MacOS that support FD_CLOEXEC, an accepted socket is given that flag so that it is not shared with a subprocess created by subprocess.

If a connection cannot be accepted by tcp-accept, or if the listener has been closed, the exn:fail:network exception is raised.

Changed in version 8.11.1.6 of package base: Changed to use FD_CLOEXECwhere supported by the operating system.

(tcp-accept/enable-break listener) →
listener : tcp-listener?

Like tcp-accept, but breaking is enabled (seeBreaks) while trying to accept a connection. If breaking is disabled when tcp-accept/enable-break is called, then either ports are returned or the exn:break exception is raised, but not both.

Tests whether an unaccepted client has connected to the server associated with listener. If a client is waiting, the return value is #t, otherwise it is#f. A client is accepted with the tcp-acceptprocedure, which returns ports for communicating with the client and removes the client from the list of unaccepted clients.

If the listener has been closed, the exn:fail:network exception is raised.

Shuts down the server associated with listener. All unaccepted clients receive an end-of-file from the server; connections to accepted clients are unaffected.

If the listener has already been closed, the exn:fail:network exception is raised.

The listener’s port number may not become immediately available for new listeners (with the default reuse? argument oftcp-listen). For further information, see Stevens’s explanation of the TIME_WAIT TCP state.

Returns #t if v is a TCP listener created bytcp-listen, #f otherwise.

Returns a synchronizable event (see Events) that isready for synchronization when tcp-accept on listener would not block. The synchronization result is a list of two items, which correspond to the two results oftcp-accept. (If the event is not chosen in a sync, no connections are accepted.) The ports are placed into the management of the custodian that is the current custodian (see Custodians) at the time thattcp-accept-evt is called.

Like close-output-port or close-input-port(depending on whether tcp-port is an input or output port), but if tcp-port is an output port and its associated input port is not yet closed, then the other end of the TCP connection does not receive a TCP close message until the input port is also closed.

The TCP protocol does not include a “no longer reading” state on connections, so tcp-abandon-port is equivalent toclose-input-port on input TCP ports.

Returns two strings when port-numbers? is #f (the default). The first string is the Internet address for the local machine as viewed by the given TCP port’s connection, for the TCP listener, or the UDP socket. (When a machine serves multiple addresses, as it usually does if you count the loopback device, the result is connection-specific or listener-specific.) If a listener or UDP socket is given and it has no specific host, the first string result is "0.0.0.0". The second string is the Internet address for the other end of the connection, or always"0.0.0.0" for a listener or unconnected UDP socket.

If port-numbers? is true, then four results are returned: a string for the local machine’s address, an exact integer between1 and 65535 for the local machine’s port number, a string for the remote machine’s address, and an exact integer between1 and 65535 for the remote machine’s port number or0 for a listener.

If the given port, listener, or socket has been closed, theexn:fail:network exception is raised.

Returns #t if v is a TCP port—which is a port returned by tcp-accept, tcp-connect,tcp-accept/enable-break, ortcp-connect/enable-break—#f otherwise.

Added in version 6.3 of package base.

Added in version 6.3 of package base.