Socket programming in Common Lisp: how to use usocket’s with-* macros

So I have tried my hands at socket programming in Common Lisp lately, using the (widely used) usocket library.

After getting past the initial difficulties of learning how to use the library’s API (thanks to various tutorials & guides, especially this one by Sid Heroor), I’ve noticed that many people recommend using the with-* macros (specifically, with-connected-socket, with-client-socket, with-server-socket, and with-socket-listener) provided by usocket for the sake of convenience (these macros will ensure that errors are properly handled and all sockets are properly closed after we are done with them) and clarity.

Well, the only problem is that I can’t seem to find any guide or tutorial on how to use them. After searching in vain for a couple of hours, I decided to just bite the bullet and dive into usocket’s source code to see how these macros work, and, to my surprise and delight, found that these macros are very easy to understand.

Basically, all the other with-* macros are built on top of the with-connected-socket macro. The with-connected-socket macro is responsible for automatically binding a socket to a variable, passing the body to the with-mapped-conditions helper macro which handles any errors or exceptions, and ensuring that the socket is destroyed on exit. The with-client-socket macro provides a nice and convenient interface over the socket-connect function for a client to connect to a server. It not only automatically binds a socket to a variable, but also creates a socket stream for the client as well. The with-socket-listener macro provides a convenient interface over the socket-listen function, and returns the resulting socket to the with-server-socket macro. The with-server-socket macro, in turn, passes the socket that was created from the call to socket-listen to the with-connected-socket macro.

We can rewrite the example by Mr. Sid using these with-* macros as follows:

The server:

The client:

Note how these macros combined can significantly reduce boilerplate code in both the server and client, as well as making the program safer and easier to understand. This is a great example of the power of Common Lisp’s macro. In other languages, for example Python, it would require a new version of the language to introduce the equivalents of the with-* macros seen here, while in Lisp one can introduce a new control structure/expression as a part of a library! I also love how the definitions of the with-* macros themselves serve as a quasi-style guide on how to safely use the underlining functions of usocket.

Again, Common Lisp (as well as other Lisp dialects) continues to impress me, and I look forward to learning more about the language.


7 thoughts on “Socket programming in Common Lisp: how to use usocket’s with-* macros

  1. Thank you very much for the example. I feel that even the greatest lisp-libraries in the world are of no use when there is no example on how to use them.

    But there is a bug in your echo-server. It does not echo back šŸ™‚

    • Hi denis, thank you for pointing out the mistakes in my post. I went back and check the original code by Mr. Sid (that my examples were based on), and they weren’t echo server/client as well. I must be lacking sleep or something when I first wrote this. šŸ˜›

      Anyway, thanks again. I’ll fix the examples. Also, since I wrote this, I have implemented an actual echo server/client. Maybe I’ll update the post and add that as another example.

    • Of course! Please feel free to do so!

      Also, if you don’t mind, after you have done translating the post, could you give me a link to the Japanese version? I’d love to see the Japanese version. šŸ™‚

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s