## 5.22 Unit: tcp

This unit provides basic facilities for communicating over TCP sockets. The socket interface should be mostly compatible to the one found in PLT Scheme.

This unit uses the `extras` unit.

[procedure] (tcp-listen TCPPORT [BACKLOG
  )] Creates and returns a TCP listener object that listens for connections on `TCPPORT`, which should be an exact integer. `BACKLOG` specifies the number of maximally pending connections (and defaults to 4).

[procedure] (tcp-listener? X)
  Returns `#t` if `X` is a TCP listener object, or `#f` otherwise.

[procedure] (tcp-close LISTENER)
  Reclaims any resources associated with `LISTENER`.

[procedure] (tcp-accept LISTENER)
  Waits until a connection is established on the port on which `LISTENER` is listening and returns two values: an input- and output-port that can be used to communicate with the remote process.

  Note: this operation and any I/O on the ports returned will not block other running threads.

[procedure] (tcp-accept-ready? LISTENER)
  Returns `#t` if there are any connections pending on `LISTENER`, or `#f` otherwise.

[procedure] (tcp-listener-port LISTENER)
  Returns the port number assigned to `LISTENER` (If you pass `0` to `tcp-listen`, then the system will choose a port-number for you).

[procedure] (tcp-connect HOSTNAME [TCPPORT
  )] Establishes a client-side TCP connection to the machine with the name `HOSTNAME` (a string) at `TCPPORT` (an exact integer) and returns two values: an input- and output-port for communicating with the remote process.

  Note: any I/O on the ports returned will not block other running threads.

[procedure] (tcp-addresses PORT)
  Returns two values for the input- or output-port `PORT` (which should be a port returned by either `tcp-accept` or `tcp-connect`): the IP address of the local and the remote machine that are connected over the socket associated with `PORT`. The returned addresses are strings in `XXX.XXX.XXX.XXX` notation.

[procedure] (tcp-abandon-port PORT)
  Marks the socket port `PORT` as abandoned. This is mainly useful to close down a port without breaking the connection.

A very simple example follows. Say we have the two files `client.scm` and `server.scm`:

    ; client.scm
    (define-values (i o) (tcp-connect "localhost" 4242))
    (write-line "Good Bye!" o)
    (print (read-line i))

    ; server.scm
    (define l (tcp-listen 4242))
    (define-values (i o) (tcp-accept l))
    (write-line "Hello!" o)
    (print (read-line i))
    (close-input-port i)
    (close-output-port o)

    % csi -script server.scm &
    [1] 1409
    % csi -script client.scm
    Good Bye!
    Hello!