Page 1 of 1

SBCL sockets

Posted: Sun Feb 17, 2013 3:18 pm
by waylandsmith
Hi,

I'm learning CL by following along with Land of Lisp and supplementing it with my own projects. My current project has me trying to build a web server and application. However, I'm using (and want to continue using) SBCL with Eclipse, which is incompatible with the implementation-specific networking of CLISP used in the book. I've done quite a bit of googling and have read the internal SBCL reference texts on sb-bsd-sockets, but I keep running into brick walls at the most basic steps. For the moment, I'm just trying to send a stream from one SBCL REPL to another in terminal, but even this is proving impossible. I'm wondering if people on this forum could give me some advice or clarification of SBCL's socket terminology, especially on exactly how I bind a socket to an address and port (sb-bsd-sockets:socket-bind has me too confused to even know what questions to be asking).

Re: SBCL sockets

Posted: Mon Feb 18, 2013 2:17 am
by edgar-rft
I'm no SBCL socket specialist either, but the SBCL sockets example, please? thread from comp.lang.lisp gives some code examples.

Re: SBCL sockets

Posted: Mon Feb 18, 2013 9:58 am
by waylandsmith
edgar-rft wrote:I'm no SBCL socket specialist either, but the SBCL sockets example, please? thread from comp.lang.lisp gives some code examples.
Yeah, I found that forum post too. It looks promising but it is way more detailed than what I'm trying to do right now - the inadequate documentation of sb-bsd-sockets is extremely frustrating because it's been difficult to just mess around. Since I'm hoping to eventually build a webserver / framework with SBCL, it's important to me that I feel comfortable with a socket library. For now, that means starting two REPLs and sending a network stream between them, which that code example seems wayyyy too big for. At this point, I'm seriously considering using usockets or IOlib instead. Does anyone on this forum have experience with those socket libraries? Thanks for the help :)

Re: SBCL sockets

Posted: Mon Feb 18, 2013 11:30 am
by Goheeca
I tried usocket, but nothing special I did with that it was when I was beginning with Lisp so my experience doesn't worth much, nonetheless I think it's better to go with a library which is supported multiplatformly.

Re: SBCL sockets

Posted: Wed Feb 20, 2013 9:08 am
by smcnamara
Here's a bit of code I've written to run a socket listener with dispatch to worker threads in sbcl. I think it's pretty clear, but I can explain any part that doesn't make sense in more detail if that helps. I'm not sure what is going on with the sockets stuck in CLOSE, but it could simply be a failure on my part to clean up properly when I exit via an unexpected path (my exception/restart handling is in serious need of some work.) If any of the all-stars here have any helpful style or coding suggestions for me, I'd be happy to hear them. Note: I recognize that the use of the *server-mode* global is somewhat poor practice and should potentially be reworked.

Code: Select all

(defun start-socket-server (callback &key (qlen 6) (port 5432))
  "Start a server socket listening process running in it's own thread.
For each request received, <callback> is invoked in a separate thread."
  (let ((socket (make-instance 'inet-socket 
			       :type :stream 
			       :protocol :tcp)))
    ;; Seems to fix issue with sockets stuck in CLOSED state.
    (setf (sockopt-reuse-address socket) t) 
    (socket-bind socket #(0 0 0 0) port)
    (socket-listen socket qlen) ;; Number of request to queue.
    (format t "Socket is configured.  Entering listening loop.~%")
    (make-thread 
     (lambda ()
       (loop 
	  (when (not *server-mode*) (return))
	  (write-line "Listening for request.")
	  (let ((client-socket  (socket-accept socket)))
	    (funcall callback client-socket)))
       (write-line "Closing server socket.")
       (socket-close socket))
     :name "SocketServerThread")))
And here's where that code gets used:

Code: Select all

(defun run-webserver (&key (port 2540))
  (setf *server-mode* t)
  (unwind-protect 
       (let ((server-thread (start-socket-server 
			     (lambda (client-socket)
			       (run-handler-thread #'handle-web-request 
						   client-socket))
			     :port port)))
	 (join-thread server-thread :default 'DONE))))

Re: SBCL sockets

Posted: Thu Feb 21, 2013 5:49 am
by pjstirling
IMO land of lisp should just have used hunchentoot for its web server chapter. It's portable and a fully functional, unlike the toy that it presents

Re: SBCL sockets

Posted: Tue May 12, 2015 12:38 am
by hajovonta
pjstirling wrote:IMO land of lisp should just have used hunchentoot for its web server chapter. It's portable and a fully functional, unlike the toy that it presents
Or better yet, have an additional chapter based on Hunchentoot.