#lang scribble/doc @(require "mz.ss") @title[#:tag "networking" #:style 'toc]{Networking} @local-table-of-contents[] @;------------------------------------------------------------------------ @section[#:tag "tcp"]{TCP} @note-lib[racket/tcp] For information about TCP in general, see @italic{TCP/IP Illustrated, Volume 1} by W. Richard Stevens. @defproc[(tcp-listen [port-no (and/c exact-nonnegative-integer? (integer-in 0 65535))] [max-allow-wait exact-nonnegative-integer? 4] [reuse? any/c #f] [hostname (or/c string? #f) #f]) tcp-listener?]{ Creates a ``listening'' server on the local machine at the port number specified by @racket[port-no]. If @racket[port-no] is 0 the socket binds to an ephemeral port, which can be determined by calling @racket[tcp-addresses]. The @racket[max-allow-wait] argument determines the maximum number of client connections that can be waiting for acceptance. (When @racket[max-allow-wait] clients are waiting acceptance, no new client connections can be made.) If the @racket[reuse?] argument is true, then @racket[tcp-listen] will create a listener even if the port is involved in a @tt{TIME_WAIT} state. Such a use of @racket[reuse?] defeats certain guarantees of the TCP protocol; see Stevens's book for details. Furthermore, on many modern platforms, a true value for @racket[reuse?] overrides @tt{TIME_WAIT} only if the listener was previously created with a true value for @racket[reuse?]. If @racket[hostname] is @racket[#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 @racket["127.0.0.1"] as @racket[hostname] creates a listener that accepts only connections to @racket["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. Under Linux, if @racket[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.) The return value of @racket[tcp-listen] is a @deftech{TCP listener}. This value can be used in future calls to @racket[tcp-accept], @racket[tcp-accept-ready?], and @racket[tcp-close]. Each new TCP listener value is placed into the management of the current custodian (see @secref["custodians"]). If the server cannot be started by @racket[tcp-listen], the @exnraise[exn:fail:network].} @defproc[(tcp-connect [hostname string?] [port-no (and/c exact-nonnegative-integer? (integer-in 1 65535))] [local-hostname (or/c string? #f) #f] [local-port-no (or/c (and/c exact-nonnegative-integer? (integer-in 1 65535)) #f) #f]) (values input-port? output-port?)]{ Attempts to connect as a client to a listening server. The @racket[hostname] argument is the server host's Internet address name, and @racket[port-no] is the port number where the server is listening. (If @racket[hostname] is associated with multiple addresses, they are tried one at a time until a connection succeeds. The name @racket["localhost"] generally specifies the local machine.) The optional @racket[local-hostname] and @racket[local-port-no] specify the client's address and port. If both are @racket[#f] (the default), the client's address and port are selected automatically. If @racket[local-hostname] is not @racket[#f], then @racket[local-port-no] must be non-@racket[#f]. If @racket[local-port-no] is non-@racket[#f] and @racket[local-hostname] is @racket[#f], then the given port is used but the address is selected automatically. Two values are returned by @racket[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 @racket[tcp-accept]. These ports are placed into the management of the current custodian (see @secref["custodians"]). Initially, the returned input port is block-buffered, and the returned output port is block-buffered. Change the buffer mode using @racket[file-stream-buffer-mode]. Both of the returned ports must be closed to terminate the TCP connection. When both ports are still open, closing the output port with @racket[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, @racket[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. If a connection cannot be established by @racket[tcp-connect], the @exnraise[exn:fail:network].} @defproc[(tcp-connect/enable-break [hostname string?] [port-no (and/c exact-nonnegative-integer? (integer-in 1 65535))] [local-hostname (or/c string? #f) #f] [local-port-no (or/c (and/c exact-nonnegative-integer? (integer-in 1 65535)) #f)]) (values input-port? output-port?)]{ Like @racket[tcp-connect], but breaking is enabled (see @secref["breakhandler"]) while trying to connect. If breaking is disabled when @racket[tcp-connect/enable-break] is called, then either ports are returned or the @racket[exn:break] exception is raised, but not both.} @defproc[(tcp-accept [listener tcp-listener?]) (values input-port? output-port?)]{ Accepts a client connection for the server associated with @racket[listener]. If no client connection is waiting on the listening port, the call to @racket[tcp-accept] will block. (See also @racket[tcp-accept-ready?].) Two values are returned by @racket[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 (see @secref["custodians"]). In terms of buffering and connection states, the ports act the same as ports from @racket[tcp-connect]. If a connection cannot be accepted by @racket[tcp-accept], or if the listener has been closed, the @exnraise[exn:fail:network].} @defproc[(tcp-accept/enable-break [listener tcp-listener?]) (values input-port? output-port?)]{ Like @racket[tcp-accept], but breaking is enabled (see @secref["breakhandler"]) while trying to accept a connection. If breaking is disabled when @racket[tcp-accept/enable-break] is called, then either ports are returned or the @racket[exn:break] exception is raised, but not both.} @defproc[(tcp-accept-ready? [listener tcp-listener?]) boolean?]{ Tests whether an unaccepted client has connected to the server associated with @racket[listener]. If a client is waiting, the return value is @racket[#t], otherwise it is @racket[#f]. A client is accepted with the @racket[tcp-accept] procedure, 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 @exnraise[exn:fail:network].} @defproc[(tcp-close [listener tcp-listener?]) void?]{ Shuts down the server associated with @racket[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 @exnraise[exn:fail:network]. The listener's port number may not become immediately available for new listeners (with the default @racket[reuse?] argument of @racket[tcp-listen]). For further information, see Stevens's explanation of the @tt{TIME_WAIT} TCP state.} @defproc[(tcp-listener? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a @tech{TCP listener} created by @racket[tcp-listen], @racket[#f] otherwise.} @defproc[(tcp-accept-evt [listener tcp-listener?]) evt?]{ Returns a @tech{synchronizable event} (see @secref["sync"]) that is in a blocking state when @racket[tcp-accept] on @racket[listener] would block. If the event is chosen in a synchronization, the result is a list of two items, which correspond to the two results of @racket[tcp-accept]. (If the event is not chosen, no connections are accepted.) The ports are placed into the management of the custodian that is the current custodian (see @secref["custodians"]) at the time that @racket[tcp-accept-evt] is called.} @defproc[(tcp-abandon-port [tcp-port tcp-port?]) void?]{ Like @racket[close-output-port] or @racket[close-input-port] (depending on whether @racket[tcp-port] is an input or output port), but if @racket[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 @racket[tcp-abandon-port] is equivalent to @racket[close-input-port] on input @tech{TCP ports}.} @defproc[(tcp-addresses [tcp-port (or/c tcp-port? tcp-listener?)] [port-numbers? any/c #f]) (or/c (values string? string?) (values string? (integer-in 1 65535) string? (integer-in 0 65535)))]{ Returns two strings when @racket[port-numbers?] is @racket[#f] (the default). The first string is the Internet address for the local machine a viewed by the given @tech{TCP port}'s connection or for the TCP listener. (For most machines, the answer corresponds to the current machine's only Internet address, but when a machine serves multiple addresses, the result is connection-specific or listener-specific.) If a listener is given and it has no specific host, the first string result is @racket["0.0.0.0"]. The second string is the Internet address for the other end of the connection, or always @racket["0.0.0.0"] for a listener. If @racket[port-numbers?] is true, then four results are returned: a string for the local machine's address, an exact integer between @racket[1] and @racket[65535] for the local machine's port number, a string for the remote machine's address, and an exact integer between @racket[1] and @racket[65535] for the remote machine's port number or @racket[0] for a listener. If the given port has been closed, the @exnraise[exn:fail:network].} @defproc[(tcp-port? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a @deftech{TCP port}---which is a port returned by @racket[tcp-accept], @racket[tcp-connect], @racket[tcp-accept/enable-break], or @racket[tcp-connect/enable-break]---@racket[#f] otherwise.} @;------------------------------------------------------------------------ @section[#:tag "udp"]{UDP} @note-lib[racket/udp] For information about UDP in general, see @italic{TCP/IP Illustrated, Volume 1} by W. Richard Stevens. @defproc[(udp-open-socket [family-hostname (or/c string? #f) #f] [family-port-no (or/c string? #f) #f]) udp?]{ Creates and returns a @deftech{UDP socket} to send and receive datagrams (broadcasting is allowed). Initially, the socket is not bound or connected to any address or port. If @racket[family-hostname] or @racket[family-port-no] is not @racket[#f], then the socket's protocol family is determined from these arguments. The socket is @italic{not} bound to the hostname or port number. For example, the arguments might be the hostname and port to which messages will be sent through the socket, which ensures that the socket's protocol family is consistent with the destination. Alternately, the arguments might be the same as for a future call to @racket[udp-bind!], which ensures that the socket's protocol family is consistent with the binding. If neither @racket[family-hostname] nor @racket[family-port-no] is non-@racket[#f], then the socket's protocol family is IPv4.} @defproc[(udp-bind! [udp-socket udp?] [hostname-string (or/c string? #f)] [port-no (and/c exact-nonnegative-integer? (integer-in 0 65535))]) void?]{ Binds an unbound @racket[udp-socket] to the local port number @racket[port-no]. If @racket[port-no] is 0 the @racket[udp-socket] is bound to an ephemeral port, which can be determined by calling @racket[udp-addresses]. If @racket[hostname-string] is @racket[#f], then the socket accepts connections to all of the listening machine's IP addresses at @racket[port-no]. Otherwise, the socket accepts connections only at the IP address associated with the given name. For example, providing @racket["127.0.0.1"] as @racket[hostname-string] typically creates a listener that accepts only connections to @racket["127.0.0.1"] from the local machine. A socket cannot receive datagrams until it is bound to a local address and port. If a socket is not bound before it is used with a sending procedure @racket[udp-send], @racket[udp-send-to], etc., the sending procedure binds the socket to a random local port. Similarly, if an event from @racket[udp-send-evt] or @racket[udp-send-to-evt] is chosen for a synchronization (see @secref["sync"]), the socket is bound; if the event is not chosen, the socket may or may not become bound. The binding of a bound socket cannot be changed, with one exception: on some systems, if the socket is bound automatically when sending, if the socket is disconnected via @racket[udp-connect!], and if the socket is later used again in a send, then the later send may change the socket's automatic binding. If @racket[udp-socket] is already bound or closed, the @exnraise[exn:fail:network].} @defproc[(udp-connect! [udp-socket udp?] [hostname-string (or/c string? #f)] [port-no (or/c (and/c exact-nonnegative-integer? (integer-in 1 65535)) #f)]) void?]{ Connects the socket to the indicated remote address and port if @racket[hostname-string] is a string and @racket[port-no] is an exact integer. If @racket[hostname-string] is @racket[#f], then @racket[port-no] also must be @racket[#f], and the port is disconnected (if connected). If one of @racket[hostname-string] or @racket[port-no] is @racket[#f] and the other is not, the @exnraise[exn:fail:contract]. A connected socket can be used with @racket[udp-send] (not @racket[udp-send-to]), and it accepts datagrams only from the connected address and port. A socket need not be connected to receive datagrams. A socket can be connected, re-connected, and disconnected any number of times. If @racket[udp-socket] is closed, the @exnraise[exn:fail:network].} @defproc[(udp-send-to [udp-socket udp?] [hostname string?] [port-no (and/c exact-nonnegative-integer? (integer-in 1 65535))] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) void]{ Sends @racket[(subbytes bytes start-pos end-pos)] as a datagram from the unconnected @racket[udp-socket] to the socket at the remote machine @racket[hostname-address] on the port @racket[port-no]. The @racket[udp-socket] need not be bound or connected; if it is not bound, @racket[udp-send-to] binds it to a random local port. If the socket's outgoing datagram queue is too full to support the send, @racket[udp-send-to] blocks until the datagram can be queued. If @racket[start-pos] is greater than the length of @racket[bstr], or if @racket[end-pos] is less than @racket[start-pos] or greater than the length of @racket[bstr], the @exnraise[exn:fail:contract]. If @racket[udp-socket] is closed or connected, the @exnraise[exn:fail:network].} @defproc[(udp-send [udp-socket udp?] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) void]{ Like @racket[udp-send-to], except that @racket[udp-socket] must be connected, and the datagram goes to the connection target. If @racket[udp-socket] is closed or unconnected, the @exnraise[exn:fail:network].} @defproc[(udp-send-to* [udp-socket udp?] [hostname string?] [port-no (and/c exact-nonnegative-integer? (integer-in 1 65535))] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) boolean?]{ Like @racket[udp-send-to], but never blocks; if the socket's outgoing queue is too full to support the send, @racket[#f] is returned, otherwise the datagram is queued and the result is @racket[#t].} @defproc[(udp-send* [udp-socket udp?] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) boolean?]{ Like @racket[udp-send], except that (like @racket[udp-send-to]) it never blocks and returns @racket[#f] or @racket[#t].} @defproc[(udp-send-to/enable-break [udp-socket udp?] [hostname string?] [port-no (and/c exact-nonnegative-integer? (integer-in 1 65535))] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) void]{ Like @racket[udp-send-to], but breaking is enabled (see @secref["breakhandler"]) while trying to send the datagram. If breaking is disabled when @racket[udp-send-to/enable-break] is called, then either the datagram is sent or the @racket[exn:break] exception is raised, but not both.} @defproc[(udp-send/enable-break [udp-socket udp?] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) void]{ Like @racket[udp-send], except that breaks are enabled like @racket[udp-send-to/enable-break].} @defproc[(udp-receive! [udp-socket udp?] [bstr (and/c bytes? (not immutable?))] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) (values exact-nonnegative-integer? string? (integer-in 1 65535))]{ Accepts up to @math{@racket[end-pos]-@racket[start-pos]} bytes of @racket[udp-socket]'s next incoming datagram into @racket[bstr], writing the datagram bytes starting at position @racket[start-pos] within @racket[bstr]. The @racket[udp-socket] must be bound to a local address and port (but need not be connected). If no incoming datagram is immediately available, @racket[udp-receive!] blocks until one is available. Three values are returned: the number of received bytes (between @racket[0] and @math{@racket[end-pos]-@racket[start-pos]}, a hostname string indicating the source address of the datagram, and an integer indicating the source port of the datagram. If the received datagram is longer than @math{@racket[end-pos]-@racket[start-pos]} bytes, the remainder is discarded. If @racket[start-pos] is greater than the length of @racket[bstr], or if @racket[end-pos] is less than @racket[start-pos] or greater than the length of @racket[bstr], the @exnraise[exn:fail:contract].} @defproc[(udp-receive!* [udp-socket udp?] [bstr (and/c bytes? (not immutable?))] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) (values (or/c exact-nonnegative-integer? #f) (or/c string? #f) (or/c (integer-in 1 65535) #f))]{ Like @racket[udp-receive!], except that it never blocks. If no datagram is available, the three result values are all @racket[#f].} @defproc[(udp-receive!/enable-break [udp-socket udp?] [bstr (and/c bytes? (not immutable?))] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) (values exact-nonnegative-integer? string? (integer-in 1 65535))]{ Like @racket[udp-receive!], but breaking is enabled (see @secref["breakhandler"]) while trying to receive the datagram. If breaking is disabled when @racket[udp-receive!/enable-break] is called, then either a datagram is received or the @racket[exn:break] exception is raised, but not both.} @defproc[(udp-close [udp-socket udp?]) void?]{ Closes @racket[udp-socket], discarding unreceived datagrams. If the socket is already closed, the @exnraise[exn:fail:network].} @defproc[(udp? [v any/c]) boolean?]{ Returns @racket[#t] if @racket[v] is a socket created by @racket[udp-open-socket], @racket[#f] otherwise.} @defproc[(udp-bound? [udp-socket udp?]) boolean?]{ Returns @racket[#t] if @racket[udp-socket] is bound to a local address and port, @racket[#f] otherwise.} @defproc[(udp-connected? [udp-socket udp?]) boolean?]{ Returns @racket[#t] if @racket[udp-socket] is connected to a remote address and port, @racket[#f] otherwise.} @defproc[(udp-send-ready-evt [udp-socket udp?]) evt?]{ Returns a @tech{synchronizable event} (see @secref["sync"]) that is in a blocking state when @racket[udp-send-to] on @racket[udp-socket] would block.} @defproc[(udp-receive-ready-evt [udp-socket udp?]) evt?]{ Returns a @tech{synchronizable event} (see @secref["sync"]) that is in a blocking state when @racket[udp-receive!] on @racket[udp-socket] would block.} @defproc[(udp-send-to-evt [udp-socket udp?] [hostname string?] [port-no (and/c exact-nonnegative-integer? (integer-in 1 65535))] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) evt?]{ Returns a @tech{synchronizable event}. The event is in a blocking state when @racket[udp-send-to] on @racket[udp-socket] would block. Otherwise, if the event is chosen in a synchronization, data is sent as for @racket[(udp-send-to udp-socket hostname-address port-no bstr start-pos end-pos)], and the synchronization result is @|void-const|. (No bytes are sent if the event is not chosen.)} @defproc[(udp-send-evt [udp-socket udp?] [bstr bytes?] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) evt?]{ Returns a @tech{synchronizable event}. The event is in a blocking state when @racket[udp-send] on @racket[udp-socket] would block. Otherwise, if the event is chosen in a synchronization, data is sent as for @racket[(udp-send-to udp-socket bstr start-pos end-pos)], and the synchronization result is @|void-const|. (No bytes are sent if the event is not chosen.) If @racket[udp-socket] is closed or unconnected, the @exnraise[exn:fail:network] during a synchronization attempt.} @defproc[(udp-receive!-evt [udp-socket udp?] [bstr (and/c bytes? (not immutable?))] [start-pos exact-nonnegative-integer? 0] [end-pos exact-nonnegative-integer? (bytes-length bstr)]) evt?]{ Returns a @tech{synchronizable event}. The event is in a blocking state when @racket[udp-receive] on @racket[udp-socket] would block. Otherwise, if the event is chosen in a synchronization, data is received into @racket[bstr] as for @racket[(udp-receive! udp-socket bytes start-pos end-pos)], and the synchronization result is a list of three values, corresponding to the three results from @racket[udp-receive!]. (No bytes are received and the @racket[bstr] content is not modified if the event is not chosen.)} @defproc[(udp-addresses [udp-port udp?] [port-numbers? any/c #f]) (or/c (values string? string?) (values string? (integer-in 0 65535) string? (integer-in 0 65535)))]{ Returns two strings when @racket[port-numbers?] is @racket[#f] (the default). The first string is the Internet address for the local machine a viewed by the given @tech{UDP socket}'s connection. (For most machines, the answer corresponds to the current machine's only Internet address, but when a machine serves multiple addresses, the result is connection-specific.) The second string is the Internet address for the other end of the connection. If @racket[port-numbers?] is true, then four results are returned: a string for the local machine's address, an exact integer between @racket[1] and @racket[65535] for the local machine's port number or @racket[0] if the socket is unbound, a string for the remote machine's address, and an exact integer between @racket[1] and @racket[65535] for the remote machine's port number or @racket[0] if the socket is unconnected. If the given port has been closed, the @exnraise[exn:fail:network].}