Similarly to exiting the Common Lisp implementation, defining streams intimately and dynamically, or making use of multiple threads in program execution, among other features, Common Lisp requires code that isn't portable for instating network connections, if this is provided for at all. This library is a light experiment in pursuit of making this simple, starting with TCP/IPv4.
This EASY-PEASY-TCP library was created to experiment with a simple TCP client interface and so also for writing simple network clients. I hold the opinion that the available Common Lisp libraries are complicated, mostly merely mirroring the baroque system interfaces presented with little abstraction and whatnot, and that this should be as trivial as it possibly can be. Simply put, I don't want the use of a TCP client connection to be any more involved than using the file system. This is also why there is a distinction made between client and server, as these are fundamentally different concepts and deserve fundamentally different interfaces.
This library is licensed under the Creative Commons Zero Public Domain Dedication.
This design is one function, a macro, and two conditions. This lone function is OPEN-TCP-CONNECTION and will ERROR with TCP-CONNECT-ERROR in the case of being unable to ESTABLISH a connection and with TCP-ERROR for all remaining failure cases; this function will return a STREAM and that may be closed with the standard CLOSE. The lone macro is WITH-TCP-CONNECTION and is analogous to WITH-OPEN-STREAM and WITH-OPEN-FILE. An IP address is represented as a SEQUENCE of the appropriate number of octets, with ports also being represented with simple integers with the appropriate bounds. This is an easy and trivial such interface and is more than suitable for basic network programs.
It's noteworthy this interface isn't ideal, I think. From IETF RFC 793: the OPEN is present, albeit only capable of an active connection here, capable of a timeout, but this is lacking any of the more advanced options that TCP clients should have available; the SEND and RECEIVE are missing, but these can mostly be suitably replicated by the standard READing and PRINTing functions, although a refined control over or notice of the PUSH and URGENT flags would be pleasant; the CLOSE is rather accounted for; there is effectively no STATUS provided; and the ABORT is rather accounted for by that standard CLOSE mechanism.
An ideal TCP client interface would, I think, permit creating an active connection to any IP address and TCP port with sensible default values for TCP extensions and other perhaps necessary but obscure options, such as timeouts, with that in particular defaulting to an indefinite and blocking waiting. The establishment, lifetime, and closing of TCP connections should have finely-grained CONDITIONs to enable better error handling. A prime issue with lacking explicit SEND and RECEIVE functionality is a current inability to provide CONDITIONs supplied by the library for certain failure cases and that aforementioned PUSH and URGENT flag control; a compromise would be providing such explicit functions for those cases where this is wanted and otherwise using normal functions, which makes this simpler, yet results in no loss of expressiveness. It would perhaps be nice to have an OPEN symbol that will exist solely to provide the illusion of a uniform interface for networking, over that standard OPEN.
As mentioned, this library is experimental, and it currently only works under the SBCL and the CLISP implementations. There are likely bugs, as I've only glanced at the relevant documentation, and the implementation may be unnecessarily complex, inefficient, or otherwise unsuited for practical usage. I may improve this library dramatically later or I may leave this and create a new such library when I seek to improve upon the idea. I may choose to add more details to the ideal TCP client interface idea, later.
Here is the source and the documentation.