### 15.8 TCP Sockets

MIT/GNU Scheme provides access to sockets, which are a mechanism for inter-process communication. TCP stream sockets are supported, which communicate between computers over a TCP/IP network. TCP sockets are supported on all operating systems.

TCP sockets have two distinct interfaces: one interface to implement a client and another to implement a server. The basic protocol is that servers set up a listening port and wait for connections from clients. Implementation of clients is simpler and will be treated first.

The socket procedures accept two special arguments, called host-name and service. Host-name is a string which must be the name of an internet host. It is looked up using the ordinary lookup rules for your computer. For example, if your host is `foo.mit.edu` and host-name is `"bar"`, then it specifies `bar.mit.edu`.

Service specifies the service to which you will connect. A networked computer normally provides several different services, such as telnet or FTP. Each service is associated with a unique port number; for example, the `"www"` service is associated with port `80`. The service argument specifies the port number, either as a string, or directly as an exact non-negative integer. Port strings are decoded by the operating system using a table; for example, on unix the table is in `/etc/services`. Usually you will use a port string rather than a number.

procedure: open-tcp-stream-socket host-name service

  `open-tcp-stream-socket` opens a connection to the host specified by host-name. Host-name is looked up using the ordinary lookup rules for your computer. The connection is established to the service specified by service. The returned value is an I/O port, to which you can read and write characters using ordinary Scheme I/O procedures such as `read-char` and `write-char`.

  When you wish to close the connection, just use `close-port`.

  As an example, here is how you can open a connection to a web server:

      (open-tcp-stream-socket "web.mit.edu" "www")

Next we will treat setting up a TCP server, which is slightly more complicated. Creating a server is a two-part process. First, you must open a server socket, which causes the operating system to listen to the network on a port that you specify. Once the server socket is opened, the operating system will allow clients to connect to your computer on that port.

In the second step of the process, you accept the connection, which completes the connection initiated by the client, and allows you to communicate with the client. Accepting a connection does not affect the server socket; it continues to listen for additional client connections. You can have multiple client connections to the same server socket open simultaneously.

procedure: open-tcp-server-socket service [address]

  This procedure opens a server socket that listens for connections to service; the socket will continue to listen until you close it. The returned value is a server socket object.

  An error is signalled if another process is already listening on the service. Additionally, ports whose number is less than `1024` are privileged on many operating systems, and cannot be used by non-privileged processes; if service specifies such a port and you do not have administrative privileges, an error may be signalled.

  The optional argument address specifies the IP address on which the socket will listen. If this argument is not supplied or is given as `#f`, then the socket listens on all IP addresses for this machine. (This is equivalent to passing the result of calling `host-address-any`.)

procedure: tcp-server-connection-accept server-socket block? peer-address [line-translation]

  Checks to see if a client has connected to server-socket. If so, an I/O port is returned. The returned port can be read and written using ordinary Scheme I/O procedures such as `read-char` and `write-char`.

  The argument block? says what to do if no client has connected at the time of the call. If `#f`, it says to return immediately with two values of `#f`. Otherwise, the call waits until a client connects.

  The argument peer-address is either `#f` or an IP address as allocated by `allocate-host-address`. If it is an IP address, the address is modified to be the address of the client making the connection.

  The optional argument line-translation specifies how end-of-line characters will be translated when reading or writing to the returned socket. If this is unspecified or `#f`, then lines will be terminated by CR-LF, which is the standard for most internet protocols. Otherwise, it must be a string, which specifies the line-ending character sequence to use.

  Note that closing the port returned by this procedure does not affect server-socket; it just closes the particular client connection that was opened by the call. To close server-socket, use `close-tcp-server-socket`.

procedure: close-tcp-server-socket server-socket

  Closes the server socket server-socket. The operating system will cease listening for network connections to that service. Client connections to server-socket that have already been accepted will not be affected.