[Top] [Contents] [Index] [ ? ]

TRIVIAL-SOCKETS: a socket interface for scripting and interactive use

This manual describes TRIVIAL-SOCKETS, a simple socket interface for Common Lisp programs and libraries.

Copyright © 2004 Daniel Barlow and contributors

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

1. Introduction

TRIVIAL-SOCKETS is a portable socket interface that allows CL programs to open connected (client) stream sockets to network services (e.g. HTTP, FTP, SMTP servers) and communicate with them. It's intended mostly for use by small “script” programs and for interactive use where the effort involved in writing one's own portable wrapper layer for several Lisp implementations would outweigh that spent on the actual application.

In the interests of simplicity and ease of porting, the functionality available through TRIVIAL-SOCKETS has been deliberately restricted. For a more general sockets interface which may allow access to more functionality, the reader is encouraged to consult his Lisp implementation's documentation.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2. Installation

TRIVIAL-SOCKETS is distributed via asdf-install. If you are on the Internet and your Lisp implementation has asdf-install available, you may download and compile this package with an invocation like

 
(asdf-install:install 'trivial-sockets)

The trivial-sockets package has been PGP-signed by Daniel Barlow, and asdf-install will by default check that the signature is good and that a trust path exists between you and him. If not, you will be prompted for a decision on whether to install anyway. See asdf-install documentation for more details on how this works.

Once you have installed trivial-sockets, the next time you wish to load it you need only evaluate

 
(asdf:operate 'asdf:load-op 'trivial-sockets)

or if you have an asdf system that uses it, add trivial-sockets to the :depends-on clause of that system and it will be loaded whenever your system is.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3. API


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.1 Types

A host designator is one of the following:

  1. A string, which is resolved as a hostname by the system resolver, typically using DNS or YP or some other implementation-defined mechanism. For example, "www.google.com"
  2. An IPv4 address in "dotted quad" notation: e.g. "127.0.0.1"
  3. (Implementation-defined): An IPv4 address in whatever “native” format the implementation uses to represent same, if applicable. For example, #(127 0 0 1) or 2130706433
  4. The keyword :ANY, which corresponds to INADDR_ANY or "0.0.0.0"

A protocol specifier is a keyword naming an IANA protocol number (as typically found in ‘/etc/protocols’ on Unix-like systems) or the corresponding number. Implementations must support :TCP at a minimum.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.2 Functions

Function: open-stream peer-host peer-port &key local-host local-port external-format element-type protocol

⇒ stream

Arguments and Values:

peer-host–a host designator.

peer-port–an integer.

local-host–a host designator. The default is :any.

local-port–an integer. The default is 0.

external-format–an external file format designator. The default is :default.

element-type–a type specifier; see the Common Lisp function open for valid values. The default is 'character.

protocol–a protocol specifier. The default is :tcp.

Description:

Return a stream to the named service, open for both reading and writing. The stream is usually buffered, so be sure to use force-output where necessary.

If the stream cannot be created for any reason, an error of type socket-error is signaled.

The stream should be closed in the usual way when no longer needed: see the Common Lisp functions close, with-open-stream

Function: open-server &key host port reuse-address backlog protocol

⇒ server socket

Arguments and Values:

host–a host designator. The default is :any.

port–an integer. The default is 0.

reuse-addresst or nil. The default is t.

backlog–an integer. The default is 1.

protocol–a protocol specifier. The default is :tcp.

Description:

Create a listening server socket. If port is 0, an unused port will be chosen by the implementation/operating system. Host may be set to the address of any local network interface to restrict the socket to that interface.

If reuse-address is true (the default, as recommended by Stevens) then the SO_REUSEADDR socket option will be set, which allows the the port to be reused immediately after it has been closed, without waiting for a timeout (“2*MSL”) to expire.

Backlog sets how many pending connections are queued by the operating system.

If the socket cannot be created for any reason, an error of type socket-error is signaled.

The nature of the object returned is implementation-dependent. When the socket is no longer needed it should be closed with close-server.

See Macro with-server.

Function: close-server server

⇒ result

Arguments and Values:

server–a server socket.

result–implementation-dependent.

Description:

Close server and release all resources associated with it. Note that opening a new server on the same address/port will not be immediately possible unless the earlier server was created with the :reuse-address argument.

Macro: with-server (server args) declaration* form*

⇒ results

Arguments and Values:

server–a variable.

args–a list of arguments.

declaration–a declare expression.

forms–an implicit progn.

results–the values returned by the forms.

Description:

with-server uses open-server to create a server socket named by server. Args are used as keyword arguments to open-server.

with-server evaluates the forms as an implicit progn with server bound to the value returned by open-server.

When control leaves the body, either normally or abnormally (such as by use of throw), the server socket is automatically closed.

The consequences are undefined if an attempt is made to assign to the variable server within the body forms.

Function: accept-connection server &key external-format element-type

⇒ stream

Arguments and Values:

server–a server socket.

external-format–an external file format designator. The default is :default.

element-type–a type specifier; see the Common Lisp function open for valid values. The default is 'character.

Description:

Accept a connection to server, returning a stream connected to the client which is open for both reading and writing. The stream is usually buffered, so be sure to use force-output where necessary.

If no connection is pending, accept-connection waits until one arrives.

If anything goes wrong, an error of type socket-error is signaled.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3 Examples


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3.1 Simple client

 
;; this is not HTTP compliant, really.  But it's good enough
;; for a demonstration
(with-open-stream (s (trivial-sockets:open-stream "www.google.com" 80)) 
  (format s "HEAD / HTTP/1.0~%Host: www.google.com~%~%") 
  (force-output s) 
  (loop 
    (let ((l (read-line s nil nil))) 
      (unless l (return)) 
      (princ l) (terpri))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.3.2 Simple (single-threaded) server

 
(trivial-sockets:with-server (s (:port 8913 :reuse-address t))
   (loop
    (with-open-stream (c (trivial-sockets:accept-connection s)) 
        (read-line c)
        (format c "This is a compliant though pointless implementation ~
of the finger protocol~%"))))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.4 Errors

Condition: unsupported

Class precedence list: error

This exists so that partial implementations of this interface may be created for environments which are incapable of supporting the full API. An unsupported error is signaled if the user requests functionality that is not implemented for the Lisp environment in use.

Condition: socket-error

Class precedence list: error

A socket-error error is signaled when an error situation occurs during opening of the stream. If you need more detail, this is probably a sign that you have outgrown this interface and will have to resort to unportable code (error codes vary between systems:were you expecting HOST_UNREACH or NET_UNREACH?). With that in mind, you can access the implementation-specific error using

 
(socket-nested-error condition)

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4. Implementation-dependent

Not all features in this interface are supported on all platforms, owing to deficiencies in the underlying socket layers that it uses.

Many implementations signal socket-related errors using non-specific error classes such as ERROR or SIMPLE-ERROR. (Some others, perhaps, signal more specific errors but the code in trivial-sockets does not know that. Patches welcome). Where we don't know of a specific error, we catch the general ones and resignal SOCKET-ERROR, so it's possible sometimes that errors shich are nothing at all to do with sockets (e.g. keyboard interrupts or external signals) also get presented as SOCKET-ERRORs. This applies in all implementations listed except where noted.

Patches to improve per-implementation support for this interface are welcome. Patches which include an appropriate update for the manual are doubly if not sevenfoldly so.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

Index

Jump to:   A   C   O   S   U   W  
Index Entry Section

A
accept-connection3.2 Functions

C
close-server3.2 Functions

O
open-server3.2 Functions
open-stream3.2 Functions

S
socket-error3.4 Errors

U
unsupported3.4 Errors

W
with-server3.2 Functions

Jump to:   A   C   O   S   U   W  

[Top] [Contents] [Index] [ ? ]

Table of Contents


[Top] [Contents] [Index] [ ? ]

About This Document

This document was generated by root on July, 24 2008 using texi2html 1.78.

The buttons in the navigation panels have the following meaning:

Button Name Go to From 1.2.3 go to
[ < ] Back Previous section in reading order 1.2.2
[ > ] Forward Next section in reading order 1.2.4
[ << ] FastBack Beginning of this chapter or previous chapter 1
[ Up ] Up Up section 1.2
[ >> ] FastForward Next chapter 2
[Top] Top Cover (top) of document  
[Contents] Contents Table of contents  
[Index] Index Index  
[ ? ] About About (help)  

where the Example assumes that the current position is at Subsubsection One-Two-Three of a document of the following structure:


This document was generated by root on July, 24 2008 using texi2html 1.78.