# Programming with Sockets

## Overview

&CCL; supports the socket abstraction for interprocess communication. A socket represents a connection to another process, typically (but not necessarily) a TCP/IP network connection to a client or server running on some other machine on the network.

All symbols mentioned in this chapter are exported from the CCL package. As of version 0.13, these symbols are additionally exported from the OPENMCL-SOCKET package.

&CCL; supports three types of sockets: TCP sockets, UDP sockets, and Unix-domain sockets. This should be enough for all but the most esoteric network situations. All sockets are created by . The type of socket depends on the arguments to it, as follows:

tcp-stream

  A buffered bi-directional stream over a TCP/IP connection. tcp-stream is a subclass of stream, and you can read and write to it using all the usual stream functions. Created by (make-socket :address-family :internet :type :stream :connect :active ...) or by (accept-connection ...).

file-socket-stream

  A buffered bi-directional stream over a "UNIX domain" connection. file-socket-stream is a subclass of stream, and you can read and write to it using all the usual stream functions. Created by (make-socket :address-family :file :type :stream :connect :active ...) or by (accept-connection ...),

listener-socket

  A passive socket used to listen for incoming TCP/IP connections on a particular port. A listener-socket is not a stream. It doesn't support I/O. It can only be used to create new tcp-streams by accept-connection. Created by (make-socket :type :stream :connect :passive ...)

file-listener-socket

  A passive socket used to listen for incoming UNIX domain connections named by a file in the local filesystem. A listener-socket is not a stream. It doesn't support I/O. It can only be used to create new file-socket-streams by accept-connection. Created by (make-socket :address-family :file :type :stream :connect :passive ...)

udp-socket

  A socket representing a packet-based UDP/IP connection. A udp-socket supports I/O but it is not a stream. Instead, you must use the special functions send-to and receive-from to read and write to it. Created by (make-socket :type :datagram ...)

## Sockets Dictionary

### MAKE-SOCKET

Function

    make-socket &key;
    	  address-family type connect eol format remote-host
    	  remote-port local-host local-port local-filename
    	  remote-filename keepalive reuse-address nodelay broadcast
    	  linger backlog input-timeout output-timeout connect-timeout
    	  auto-close deadline

#### Arguments and Values

address-family

  The address/protocol family of this socket. Currently only :internet (the default), meaning IP, and :file, referring to UNIX domain addresses, are supported.

type

  One of :stream (the default) to request a connection-oriented socket, or :datagram to request a connectionless socket. The default is :stream.

connect

  This argument is only relevant to sockets of type :stream. One of :active (the default) to request a :passive to request a file or TCP listener socket.

eol

  This argument is currently ignored (it is accepted for compatibility with Franz Allegro).

format

  One of :text (the default), :binary, or :bivalent. This argument is ignored for :stream sockets for now, as :stream sockets are currently always bivalent (i.e. they support both character and byte I/O). For :datagram sockets, this argument is ignored (the format of a datagram socket is always :binary).

remote-host

  Required for TCP streams, it specifies the host to connect to (in any format acceptable to lookup-hostname). Ignored for listener sockets. For UDP sockets, it can be used to specify a default host for subsequent calls to send-to or receive-from.

remote-port

  Required for TCP streams, it specifies the port to connect to (in any format acceptable to lookup-port). Ignored for listener sockets. For UDP sockets, it can be used to specify a default port for subsequent calls to for subsequent calls to send-to or receive-from.

remote-filename

  Required for file-socket streams, it specifies the name of a file in the local filesystem (e.g., NOT mounted via NFS, AFP, SMB, ...) which names and controls access to a UNIX-domain socket.

local-host

  Allows you to specify a local host address for a listener or UDP socket, for the rare case where you want to restrict connections to those coming to a specific local address for security reasons.

local-port

  Specify a local port for a socket. Most useful for listener sockets, where it is the port on which the socket will listen for connections.

local-filename

  Required for file-listener-sockets. Specifies the name of a file in the local filesystem which is used to name a UNIX-domain socket. The actual filesystem file should not previously exist when the file-listener-socket is created; its parent directory should exist and be writable by the caller. The file used to name the socket will be deleted when the file-listener-socket is closed.

keepalive

  If true, enables the periodic transmission of "keepalive" messages.

reuse-address

  If true, allows the reuse of local ports in listener sockets, overriding some TCP/IP protocol specifications. You will need this if you are debugging a server..

nodelay

  If true, disables Nagle's algorithm, which tries to minimize TCP packet fragmentation by introducing transmission delays in the absence of replies. Try setting this if you are using a protocol which involves sending a steady stream of data with no replies and are seeing significant degradations in throughput.

broadcast

  If true, requests permission to broadcast datagrams on a UDP socket.

linger

  If specified and non-nil, should be the number of seconds the OS is allowed to wait for data to be pushed through when a close is done. Only relevant for TCP sockets.

backlog

  For a listener socket, specifies the number of connections which can be pending but not accepted. The default is 5, which is also the maximum on some operating systems.

input-timeout

  The number of seconds before an input operation times out. Must be a real number between zero and one million. If an input operation takes longer than the specified number of seconds, an `input-timeout` error is signalled. (see )

output-timeout

  The number of seconds before an output operation times out. Must be a real number between zero and one million. If an output operation takes longer than the specified number of seconds, an `output-timeout` error is signalled. (see )

connect-timeout

  The number of seconds before a connection attempt times out. [TODO: what are acceptable values?] If a connection attempt takes longer than the specified number of seconds, a `socket-error` is signalled. This can be useful if the specified interval is shorter than the interval that the OS's socket layer imposes, which is sometimes a minute or two.

auto-close

  When non-nil, any resulting socket stream will be closed when the GC can prove that the stream is unreferenced. This is done via CCL's termination mechanism [TODO add xref].

deadline

  Specifies an absolute time in internal-time-units. If an I/O operation on the stream does not complete before the deadline then a `COMMUNICATION-DEADLINE-EXPIRED` error is signalled. A deadline takes precedence over any input/output timeouts that may be set. (see )

#### Description

Creates and returns a new socket

### ACCEPT-CONNECTION

Function

    accept-connection
    	  (socket listener-socket) &key; wait

#### Arguments and Values

socket

  The listener-socket to listen on.

wait

  If true (the default), and there are no connections waiting to be accepted, waits until one arrives. If false, returns NIL immediately.

#### Description

Extracts the first connection on the queue of pending connections, accepts it (i.e. completes the connection startup protocol) and returns a new tcp-stream or file-socket-stream representing the newly established connection. The tcp stream inherits any properties of the listener socket that are relevant (e.g. :keepalive, :nodelay, etc.) The original listener socket continues to be open listening for more connections, so you can call accept-connection on it again.

### DOTTED-TO-IPADDR

Function

    dotted-to-ipaddr
    	  dotted &key; errorp

#### Arguments and Values

dotted

  A string representing an IP address in the "nn.nn.nn.nn" format

errorp

  If true (the default) an error is signaled if dotted is invalid. If false, NIL is returned.

#### Description

Converts a dotted-string representation of a host address to a 32-bit unsigned IP address.

### IPADDR-TO-DOTTED

Function

    ipaddr-to-dotted
    	  ipaddr &key; values

#### Arguments and Values

ipaddr

  A 32-bit integer representing an internet host address

values

  If false (the default), returns a string in the form "nn.nn.nn.nn". If true, returns four values representing the four octets of the address as unsigned 8-bit integers.

#### Description

Converts a 32-bit unsigned IP address into octets.

### IPADDR-TO-HOSTNAME

Function

    ipaddr-to-hostname
    	  ipaddr &key; ignore-cache

#### Arguments and Values

ipaddr

  a 32-bit integer representing an internet host address

ignore-cache

  This argument is ignored (it is accepted for compatibility with Franz Allegro)

#### Description

Converts a 32-bit unsigned IP address into a host name string

### LOOKUP-HOSTNAME

Function

    lookup-hostname
    	  host

#### Arguments and Values

host

  Specifies the host. It can be either a host name string such as "clozure.com", or a dotted address string such as "192.168.0.1", or a 32-bit unsigned IP address such as 3232235521.

#### Description

Converts a host spec in any of the acceptable formats into a 32-bit unsigned IP address

### LOOKUP-PORT

Function

    lookup-port
    	  port protocol

#### Arguments and Values

port

  Specifies the port. It can be either a string, such as "http" or a symbol, such as :http, or an unsigned port number. Note that a string is case-sensitive. A symbol is lowercased before lookup.

protocol

  Must be one of "tcp" or "udp".

#### Description

Finds the port number for the specified port and protocol

### RECEIVE-FROM

Function

    receive-from
    	  (socket udp-socket) size &key; buffer
    	  extract offset

#### Arguments and Values

socket

  The socket to read from

size

  Maximum number of bytes to read. If the packet is larger than this, any extra bytes are discarded.

buffer

  If specified, must be an octet vector which will be used to read in the data. If not specified, a new buffer will be created (of type determined by socket-format).

extract

  If true, the subsequence of the buffer corresponding only to the data read in is extracted and returned as the first value. If false (the default) the original buffer is returned even if it is only partially filled.

offset

  Specifies the start offset into the buffer at which data is to be stored. The default is 0.

#### Description

Reads a UDP packet from a socket. If no packets are available, waits for a packet to arrive. Returns four values:

1. The buffer with the data

2. The number of bytes read

3. The 32-bit unsigned IP address of the sender of the data

4. The port number of the sender of the data

### SEND-TO

Function

    send-to
    	  (socket udp-socket) buffer size &key; remote-host
    	  remote-port offset

#### Arguments and Values

socket

  The socket to write to

buffer

  A vector containing the data to send. It must be an octet vector.

size

  Number of octets to send

remote-host

  The host to send the packet to, in any format acceptable to lookup-hostname. The default is the remote host specified in the call to make-socket.

remote-port

  The port to send the packet to, in any format acceptable to lookup-port. The default is the remote port specified in the call to make-socket.

offset

  The offset in the buffer where the packet data starts

#### Description

Send a UDP packet over a socket.

### SHUTDOWN

Function

    shutdown
    	  socket &key; direction

#### Arguments and Values

socket

  The socket to shut down (typically a tcp-stream)

direction

  One of :input to disallow further input, or :output to disallow further output.

#### Description

Shuts down part of a bidirectional connection. This is useful if e.g. you need to read responses after sending an end-of-file signal.

### SOCKET-OS-FD

Function

    socket-os-fd
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

Returns the native OS's representation of the socket, or NIL if the socket is closed. On Unix, this is the Unix 'file descriptor', a small non-negative integer. Note that it is rather dangerous to mess around with tcp-stream fd's, as there is all sorts of buffering and asynchronous I/O going on above the OS level. listener-socket and udp-socket fd's are safer to mess with directly as there is less magic going on.

### REMOTE-HOST

Function

    remote-host
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

Returns the 32-bit unsigned IP address of the remote host, or NIL if the socket is not connected.

### REMOTE-PORT

Function

    remote-port
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

Returns the remote port number, or NIL if the socket is not connected.

### LOCAL-HOST

Function

    local-host
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

Returns 32-bit unsigned IP address of the local host.

### LOCAL-PORT

Function

    local-port
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

Returns the local port number

### SOCKET-ADDRESS-FAMILY

Function

    socket-address-family
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

Returns :internet or :file, as appropriate.

### SOCKET-CONNECT

Function

    socket-connect
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

Returns :active for tcp-stream, :passive for listener-socket, and NIL for udp-socket

### SOCKET-FORMAT

Function

    socket-format
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

Returns the socket format as specified by the :format argument to make-socket.

### SOCKET-TYPE

Function

    socket-type
    	  socket

#### Arguments and Values

socket

  The socket

#### Description

returns :stream for tcp-stream and listener-socket, and :datagram for udp-socket.

### SOCKET-ERROR

Class

#### Description

The class of OS errors signaled by socket functions

#### Superclasses

simple-error

### SOCKET-ERROR-CODE

Function

    socket-error-code
    	  socket-error

#### Arguments and Values

socket-error

  the condition

#### Description

The OS error code of the error

### SOCKET-ERROR-IDENTIFIER

Function

    socket-error-identifier
    	  socket-error

#### Arguments and Values

socket-error

  the condition

#### Description

A symbol representing the error code in a more OS-independent way.

One of: :address-in-use :connection-aborted :no-buffer-space :connection-timed-out :connection-refused :host-unreachable :host-down :network-down :address-not-available :network-reset :connection-reset :shutdown :access-denied or :unknown.

### SOCKET-ERROR-SITUATION

Function

    socket-error-situation
    	  socket-error

#### Arguments and Values

socket-error

  the condition

#### Description

A string describing the context where the error happened. On Linux, this is the name of the system call which returned the error.

### CLOSE

Method

    close
    	  (socket socket) &key; abort

#### Arguments and Values

socket

  The socket to close

abort

  If false (the default), closes the socket in an orderly fashion, finishing up any buffered pending I/O, before closing the connection. If true, aborts/ignores pending I/O. (For listener and udp sockets, this argument is effectively ignored since there is never any buffered I/O to clean up).

#### Description

The close generic function can be applied to sockets. It releases the operating system resources associated with the socket.

### WITH-OPEN-SOCKET

Macro

    with-open-socket
    	  (var . make-socket-args) &body; body

#### Arguments and Values

var

  variable to bind

make-socket-args

  arguments suitable for passing to make-socket

body

  body to execute

#### Description

executes body with var bound to the result of applying make-socket to make-socket-args. The socket gets closed on exit.